##// END OF EJS Templates
See last commit
perrinel -
r700:bef126514bff
parent child
Show More
@@ -1,142 +1,141
1 #include "Network/NetworkController.h"
1 #include "Network/NetworkController.h"
2
2
3 #include <QMutex>
3 #include <QMutex>
4 #include <QNetworkAccessManager>
4 #include <QNetworkAccessManager>
5 #include <QNetworkReply>
5 #include <QNetworkReply>
6 #include <QNetworkRequest>
6 #include <QNetworkRequest>
7 #include <QReadWriteLock>
7 #include <QReadWriteLock>
8 #include <QThread>
8 #include <QThread>
9
9
10 #include <unordered_map>
10 #include <unordered_map>
11
11
12 Q_LOGGING_CATEGORY(LOG_NetworkController, "NetworkController")
12 Q_LOGGING_CATEGORY(LOG_NetworkController, "NetworkController")
13
13
14 struct NetworkController::NetworkControllerPrivate {
14 struct NetworkController::NetworkControllerPrivate {
15 explicit NetworkControllerPrivate(NetworkController *parent) : m_WorkingMutex{} {}
15 explicit NetworkControllerPrivate(NetworkController *parent) : m_WorkingMutex{} {}
16
16
17 void lockRead() { m_Lock.lockForRead(); }
17 void lockRead() { m_Lock.lockForRead(); }
18 void lockWrite() { m_Lock.lockForWrite(); }
18 void lockWrite() { m_Lock.lockForWrite(); }
19 void unlock() { m_Lock.unlock(); }
19 void unlock() { m_Lock.unlock(); }
20
20
21 QMutex m_WorkingMutex;
21 QMutex m_WorkingMutex;
22
22
23 QReadWriteLock m_Lock;
23 QReadWriteLock m_Lock;
24 std::unordered_map<QNetworkReply *, QUuid> m_NetworkReplyToId;
24 std::unordered_map<QNetworkReply *, QUuid> m_NetworkReplyToId;
25 std::unique_ptr<QNetworkAccessManager> m_AccessManager{nullptr};
25 std::unique_ptr<QNetworkAccessManager> m_AccessManager{nullptr};
26 };
26 };
27
27
28 NetworkController::NetworkController(QObject *parent)
28 NetworkController::NetworkController(QObject *parent)
29 : QObject(parent), impl{spimpl::make_unique_impl<NetworkControllerPrivate>(this)}
29 : QObject(parent), impl{spimpl::make_unique_impl<NetworkControllerPrivate>(this)}
30 {
30 {
31 }
31 }
32
32
33 void NetworkController::onProcessRequested(std::shared_ptr<QNetworkRequest> request,
33 void NetworkController::onProcessRequested(std::shared_ptr<QNetworkRequest> request,
34 QUuid identifier,
34 QUuid identifier,
35 std::function<void(QNetworkReply *, QUuid)> callback)
35 std::function<void(QNetworkReply *, QUuid)> callback)
36 {
36 {
37 qCDebug(LOG_NetworkController()) << tr("NetworkController onProcessRequested")
37 qCDebug(LOG_NetworkController()) << tr("NetworkController onProcessRequested")
38 << QThread::currentThread()->objectName() << &request;
38 << QThread::currentThread()->objectName() << &request;
39 auto reply = impl->m_AccessManager->get(*request);
39 auto reply = impl->m_AccessManager->get(*request);
40
40
41 // Store the couple reply id
41 // Store the couple reply id
42 impl->lockWrite();
42 impl->lockWrite();
43 impl->m_NetworkReplyToId[reply] = identifier;
43 impl->m_NetworkReplyToId[reply] = identifier;
44 qCDebug(LOG_NetworkController()) << tr("Store for reply: ") << identifier;
44 qCDebug(LOG_NetworkController()) << tr("Store for reply: ") << identifier;
45 impl->unlock();
45 impl->unlock();
46
46
47 auto onReplyFinished = [request, reply, this, identifier, callback]() {
47 auto onReplyFinished = [request, reply, this, identifier, callback]() {
48
48
49 qCDebug(LOG_NetworkController()) << tr("NetworkController onReplyFinished")
49 qCDebug(LOG_NetworkController()) << tr("NetworkController onReplyFinished")
50 << QThread::currentThread() << request.get() << reply;
50 << QThread::currentThread() << request.get() << reply;
51 impl->lockRead();
51 impl->lockRead();
52 auto it = impl->m_NetworkReplyToId.find(reply);
52 auto it = impl->m_NetworkReplyToId.find(reply);
53 impl->unlock();
53 impl->unlock();
54 if (it != impl->m_NetworkReplyToId.cend()) {
54 if (it != impl->m_NetworkReplyToId.cend()) {
55 impl->lockWrite();
55 impl->lockWrite();
56 qCDebug(LOG_NetworkController()) << tr("Remove for reply: ")
56 qCDebug(LOG_NetworkController()) << tr("Remove for reply: ")
57 << impl->m_NetworkReplyToId[reply];
57 << impl->m_NetworkReplyToId[reply];
58 impl->m_NetworkReplyToId.erase(reply);
58 impl->m_NetworkReplyToId.erase(reply);
59 impl->unlock();
59 impl->unlock();
60 // Deletes reply
60 // Deletes reply
61 callback(reply, identifier);
61 callback(reply, identifier);
62 reply->deleteLater();
62 reply->deleteLater();
63 }
63 }
64
64
65 qCDebug(LOG_NetworkController()) << tr("NetworkController onReplyFinished END")
65 qCDebug(LOG_NetworkController()) << tr("NetworkController onReplyFinished END")
66 << QThread::currentThread() << reply;
66 << QThread::currentThread() << reply;
67 };
67 };
68
68
69 auto onReplyProgress = [reply, request, this](qint64 bytesRead, qint64 totalBytes) {
69 auto onReplyProgress = [reply, request, this](qint64 bytesRead, qint64 totalBytes) {
70
70
71 // NOTE: a totalbytes of 0 can happened when a request has been aborted
71 // NOTE: a totalbytes of 0 can happened when a request has been aborted
72 if (totalBytes > 0) {
72 if (totalBytes > 0) {
73 double progress = (bytesRead * 100.0) / totalBytes;
73 double progress = (bytesRead * 100.0) / totalBytes;
74 qCDebug(LOG_NetworkController()) << tr("NetworkController onReplyProgress") << progress
74 qCDebug(LOG_NetworkController()) << tr("NetworkController onReplyProgress") << progress
75 << QThread::currentThread() << request.get() << reply
75 << QThread::currentThread() << request.get() << reply
76 << bytesRead << totalBytes;
76 << bytesRead << totalBytes;
77 impl->lockRead();
77 impl->lockRead();
78 auto it = impl->m_NetworkReplyToId.find(reply);
78 auto it = impl->m_NetworkReplyToId.find(reply);
79 impl->unlock();
79 impl->unlock();
80 if (it != impl->m_NetworkReplyToId.cend()) {
80 if (it != impl->m_NetworkReplyToId.cend()) {
81 emit this->replyDownloadProgress(it->second, request, progress);
81 emit this->replyDownloadProgress(it->second, request, progress);
82 }
82 }
83 qCDebug(LOG_NetworkController()) << tr("NetworkController onReplyProgress END")
83 qCDebug(LOG_NetworkController()) << tr("NetworkController onReplyProgress END")
84 << QThread::currentThread() << reply;
84 << QThread::currentThread() << reply;
85 }
85 }
86 };
86 };
87
87
88
88
89 connect(reply, &QNetworkReply::finished, this, onReplyFinished);
89 connect(reply, &QNetworkReply::finished, this, onReplyFinished);
90 connect(reply, &QNetworkReply::downloadProgress, this, onReplyProgress);
90 connect(reply, &QNetworkReply::downloadProgress, this, onReplyProgress);
91 qCDebug(LOG_NetworkController()) << tr("NetworkController registered END")
91 qCDebug(LOG_NetworkController()) << tr("NetworkController registered END")
92 << QThread::currentThread()->objectName() << reply;
92 << QThread::currentThread()->objectName() << reply;
93 }
93 }
94
94
95 void NetworkController::initialize()
95 void NetworkController::initialize()
96 {
96 {
97 qCDebug(LOG_NetworkController()) << tr("NetworkController init") << QThread::currentThread();
97 qCDebug(LOG_NetworkController()) << tr("NetworkController init") << QThread::currentThread();
98 impl->m_WorkingMutex.lock();
98 impl->m_WorkingMutex.lock();
99 impl->m_AccessManager = std::make_unique<QNetworkAccessManager>();
99 impl->m_AccessManager = std::make_unique<QNetworkAccessManager>();
100
100
101
101
102 auto onReplyErrors = [this](QNetworkReply *reply, const QList<QSslError> &errors) {
102 auto onReplyErrors = [this](QNetworkReply *reply, const QList<QSslError> &errors) {
103
104 qCCritical(LOG_NetworkController()) << tr("NetworkAcessManager errors: ") << errors;
103 qCCritical(LOG_NetworkController()) << tr("NetworkAcessManager errors: ") << errors;
105
104
106 };
105 };
107
106
108
107
109 connect(impl->m_AccessManager.get(), &QNetworkAccessManager::sslErrors, this, onReplyErrors);
108 connect(impl->m_AccessManager.get(), &QNetworkAccessManager::sslErrors, this, onReplyErrors);
110
109
111 qCDebug(LOG_NetworkController()) << tr("NetworkController init END");
110 qCDebug(LOG_NetworkController()) << tr("NetworkController init END");
112 }
111 }
113
112
114 void NetworkController::finalize()
113 void NetworkController::finalize()
115 {
114 {
116 impl->m_WorkingMutex.unlock();
115 impl->m_WorkingMutex.unlock();
117 }
116 }
118
117
119 void NetworkController::onReplyCanceled(QUuid identifier)
118 void NetworkController::onReplyCanceled(QUuid identifier)
120 {
119 {
121 auto findReply = [identifier](const auto &entry) { return identifier == entry.second; };
120 auto findReply = [identifier](const auto &entry) { return identifier == entry.second; };
122 qCDebug(LOG_NetworkController()) << tr("NetworkController onReplyCanceled")
121 qCDebug(LOG_NetworkController()) << tr("NetworkController onReplyCanceled")
123 << QThread::currentThread() << identifier;
122 << QThread::currentThread() << identifier;
124
123
125
124
126 impl->lockRead();
125 impl->lockRead();
127 auto end = impl->m_NetworkReplyToId.cend();
126 auto end = impl->m_NetworkReplyToId.cend();
128 auto it = std::find_if(impl->m_NetworkReplyToId.cbegin(), end, findReply);
127 auto it = std::find_if(impl->m_NetworkReplyToId.cbegin(), end, findReply);
129 impl->unlock();
128 impl->unlock();
130 if (it != end) {
129 if (it != end) {
131 qCDebug(LOG_NetworkController()) << tr("NetworkController onReplyCanceled ABORT DONE")
130 qCDebug(LOG_NetworkController()) << tr("NetworkController onReplyCanceled ABORT DONE")
132 << QThread::currentThread() << identifier;
131 << QThread::currentThread() << identifier;
133 it->first->abort();
132 it->first->abort();
134 }
133 }
135 qCDebug(LOG_NetworkController()) << tr("NetworkController onReplyCanceled END")
134 qCDebug(LOG_NetworkController()) << tr("NetworkController onReplyCanceled END")
136 << QThread::currentThread();
135 << QThread::currentThread();
137 }
136 }
138
137
139 void NetworkController::waitForFinish()
138 void NetworkController::waitForFinish()
140 {
139 {
141 QMutexLocker locker{&impl->m_WorkingMutex};
140 QMutexLocker locker{&impl->m_WorkingMutex};
142 }
141 }
General Comments 2
You need to be logged in to leave comments. Login now