##// END OF EJS Templates
Update networkcontroller for abort mechanism
perrinel -
r698:076c09acb9f6
parent child
Show More
@@ -1,133 +1,142
1 1 #include "Network/NetworkController.h"
2 2
3 3 #include <QMutex>
4 4 #include <QNetworkAccessManager>
5 5 #include <QNetworkReply>
6 6 #include <QNetworkRequest>
7 7 #include <QReadWriteLock>
8 8 #include <QThread>
9 9
10 10 #include <unordered_map>
11 11
12 12 Q_LOGGING_CATEGORY(LOG_NetworkController, "NetworkController")
13 13
14 14 struct NetworkController::NetworkControllerPrivate {
15 15 explicit NetworkControllerPrivate(NetworkController *parent) : m_WorkingMutex{} {}
16 16
17 17 void lockRead() { m_Lock.lockForRead(); }
18 18 void lockWrite() { m_Lock.lockForWrite(); }
19 19 void unlock() { m_Lock.unlock(); }
20 20
21 21 QMutex m_WorkingMutex;
22 22
23 23 QReadWriteLock m_Lock;
24 std::unordered_map<QNetworkReply *, QUuid> m_NetworkReplyToVariableId;
24 std::unordered_map<QNetworkReply *, QUuid> m_NetworkReplyToId;
25 25 std::unique_ptr<QNetworkAccessManager> m_AccessManager{nullptr};
26 26 };
27 27
28 28 NetworkController::NetworkController(QObject *parent)
29 29 : QObject(parent), impl{spimpl::make_unique_impl<NetworkControllerPrivate>(this)}
30 30 {
31 31 }
32 32
33 33 void NetworkController::onProcessRequested(std::shared_ptr<QNetworkRequest> request,
34 34 QUuid identifier,
35 35 std::function<void(QNetworkReply *, QUuid)> callback)
36 36 {
37 37 qCDebug(LOG_NetworkController()) << tr("NetworkController onProcessRequested")
38 38 << QThread::currentThread()->objectName() << &request;
39 39 auto reply = impl->m_AccessManager->get(*request);
40 40
41 41 // Store the couple reply id
42 42 impl->lockWrite();
43 impl->m_NetworkReplyToVariableId[reply] = identifier;
43 impl->m_NetworkReplyToId[reply] = identifier;
44 qCDebug(LOG_NetworkController()) << tr("Store for reply: ") << identifier;
44 45 impl->unlock();
45 46
46 47 auto onReplyFinished = [request, reply, this, identifier, callback]() {
47 48
48 49 qCDebug(LOG_NetworkController()) << tr("NetworkController onReplyFinished")
49 50 << QThread::currentThread() << request.get() << reply;
50 51 impl->lockRead();
51 auto it = impl->m_NetworkReplyToVariableId.find(reply);
52 auto it = impl->m_NetworkReplyToId.find(reply);
52 53 impl->unlock();
53 if (it != impl->m_NetworkReplyToVariableId.cend()) {
54 if (it != impl->m_NetworkReplyToId.cend()) {
54 55 impl->lockWrite();
55 impl->m_NetworkReplyToVariableId.erase(reply);
56 qCDebug(LOG_NetworkController()) << tr("Remove for reply: ")
57 << impl->m_NetworkReplyToId[reply];
58 impl->m_NetworkReplyToId.erase(reply);
56 59 impl->unlock();
57 60 // Deletes reply
58 61 callback(reply, identifier);
59 62 reply->deleteLater();
60 63 }
61 64
62 65 qCDebug(LOG_NetworkController()) << tr("NetworkController onReplyFinished END")
63 66 << QThread::currentThread() << reply;
64 67 };
65 68
66 69 auto onReplyProgress = [reply, request, this](qint64 bytesRead, qint64 totalBytes) {
67 70
68 double progress = (bytesRead * 100.0) / totalBytes;
69 qCDebug(LOG_NetworkController()) << tr("NetworkController onReplyProgress") << progress
70 << QThread::currentThread() << request.get() << reply;
71 impl->lockRead();
72 auto it = impl->m_NetworkReplyToVariableId.find(reply);
73 impl->unlock();
74 if (it != impl->m_NetworkReplyToVariableId.cend()) {
75 emit this->replyDownloadProgress(it->second, request, progress);
71 // NOTE: a totalbytes of 0 can happened when a request has been aborted
72 if (totalBytes > 0) {
73 double progress = (bytesRead * 100.0) / totalBytes;
74 qCDebug(LOG_NetworkController()) << tr("NetworkController onReplyProgress") << progress
75 << QThread::currentThread() << request.get() << reply
76 << bytesRead << totalBytes;
77 impl->lockRead();
78 auto it = impl->m_NetworkReplyToId.find(reply);
79 impl->unlock();
80 if (it != impl->m_NetworkReplyToId.cend()) {
note

ok

81 emit this->replyDownloadProgress(it->second, request, progress);
82 }
83 qCDebug(LOG_NetworkController()) << tr("NetworkController onReplyProgress END")
84 << QThread::currentThread() << reply;
76 85 }
77 qCDebug(LOG_NetworkController()) << tr("NetworkController onReplyProgress END")
78 << QThread::currentThread() << reply;
79 86 };
80 87
81 88
82 89 connect(reply, &QNetworkReply::finished, this, onReplyFinished);
83 90 connect(reply, &QNetworkReply::downloadProgress, this, onReplyProgress);
84 91 qCDebug(LOG_NetworkController()) << tr("NetworkController registered END")
85 92 << QThread::currentThread()->objectName() << reply;
86 93 }
87 94
88 95 void NetworkController::initialize()
89 96 {
90 97 qCDebug(LOG_NetworkController()) << tr("NetworkController init") << QThread::currentThread();
91 98 impl->m_WorkingMutex.lock();
92 99 impl->m_AccessManager = std::make_unique<QNetworkAccessManager>();
93 100
94 101
95 102 auto onReplyErrors = [this](QNetworkReply *reply, const QList<QSslError> &errors) {
96 103
97 104 qCCritical(LOG_NetworkController()) << tr("NetworkAcessManager errors: ") << errors;
98 105
99 106 };
100 107
101 108
102 109 connect(impl->m_AccessManager.get(), &QNetworkAccessManager::sslErrors, this, onReplyErrors);
103 110
104 111 qCDebug(LOG_NetworkController()) << tr("NetworkController init END");
105 112 }
106 113
107 114 void NetworkController::finalize()
108 115 {
109 116 impl->m_WorkingMutex.unlock();
110 117 }
111 118
112 119 void NetworkController::onReplyCanceled(QUuid identifier)
113 120 {
114 121 auto findReply = [identifier](const auto &entry) { return identifier == entry.second; };
115 122 qCDebug(LOG_NetworkController()) << tr("NetworkController onReplyCanceled")
116 << QThread::currentThread();
123 << QThread::currentThread() << identifier;
117 124
118 125
119 126 impl->lockRead();
120 auto end = impl->m_NetworkReplyToVariableId.cend();
121 auto it = std::find_if(impl->m_NetworkReplyToVariableId.cbegin(), end, findReply);
127 auto end = impl->m_NetworkReplyToId.cend();
128 auto it = std::find_if(impl->m_NetworkReplyToId.cbegin(), end, findReply);
122 129 impl->unlock();
123 130 if (it != end) {
131 qCDebug(LOG_NetworkController()) << tr("NetworkController onReplyCanceled ABORT DONE")
132 << QThread::currentThread() << identifier;
124 133 it->first->abort();
125 134 }
126 135 qCDebug(LOG_NetworkController()) << tr("NetworkController onReplyCanceled END")
127 << QThread::currentThread();
136 << QThread::currentThread();
128 137 }
129 138
130 139 void NetworkController::waitForFinish()
131 140 {
132 141 QMutexLocker locker{&impl->m_WorkingMutex};
133 142 }
General Comments 2
You need to be logged in to leave comments. Login now