##// END OF EJS Templates
See last commit
perrinel -
r700:bef126514bff
parent child
Show More
@@ -1,142 +1,141
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 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 43 impl->m_NetworkReplyToId[reply] = identifier;
44 44 qCDebug(LOG_NetworkController()) << tr("Store for reply: ") << identifier;
45 45 impl->unlock();
46 46
47 47 auto onReplyFinished = [request, reply, this, identifier, callback]() {
48 48
49 49 qCDebug(LOG_NetworkController()) << tr("NetworkController onReplyFinished")
50 50 << QThread::currentThread() << request.get() << reply;
51 51 impl->lockRead();
52 52 auto it = impl->m_NetworkReplyToId.find(reply);
53 53 impl->unlock();
54 54 if (it != impl->m_NetworkReplyToId.cend()) {
55 55 impl->lockWrite();
56 56 qCDebug(LOG_NetworkController()) << tr("Remove for reply: ")
57 << impl->m_NetworkReplyToId[reply];
57 << impl->m_NetworkReplyToId[reply];
58 58 impl->m_NetworkReplyToId.erase(reply);
59 59 impl->unlock();
60 60 // Deletes reply
61 61 callback(reply, identifier);
62 62 reply->deleteLater();
63 63 }
64 64
65 65 qCDebug(LOG_NetworkController()) << tr("NetworkController onReplyFinished END")
66 66 << QThread::currentThread() << reply;
67 67 };
68 68
69 69 auto onReplyProgress = [reply, request, this](qint64 bytesRead, qint64 totalBytes) {
70 70
71 71 // NOTE: a totalbytes of 0 can happened when a request has been aborted
72 72 if (totalBytes > 0) {
73 73 double progress = (bytesRead * 100.0) / totalBytes;
74 74 qCDebug(LOG_NetworkController()) << tr("NetworkController onReplyProgress") << progress
75 << QThread::currentThread() << request.get() << reply
76 << bytesRead << totalBytes;
75 << QThread::currentThread() << request.get() << reply
76 << bytesRead << totalBytes;
77 77 impl->lockRead();
78 78 auto it = impl->m_NetworkReplyToId.find(reply);
79 79 impl->unlock();
80 80 if (it != impl->m_NetworkReplyToId.cend()) {
81 81 emit this->replyDownloadProgress(it->second, request, progress);
82 82 }
83 83 qCDebug(LOG_NetworkController()) << tr("NetworkController onReplyProgress END")
84 84 << QThread::currentThread() << reply;
85 85 }
86 86 };
87 87
88 88
89 89 connect(reply, &QNetworkReply::finished, this, onReplyFinished);
90 90 connect(reply, &QNetworkReply::downloadProgress, this, onReplyProgress);
91 91 qCDebug(LOG_NetworkController()) << tr("NetworkController registered END")
92 92 << QThread::currentThread()->objectName() << reply;
93 93 }
94 94
95 95 void NetworkController::initialize()
96 96 {
97 97 qCDebug(LOG_NetworkController()) << tr("NetworkController init") << QThread::currentThread();
98 98 impl->m_WorkingMutex.lock();
99 99 impl->m_AccessManager = std::make_unique<QNetworkAccessManager>();
100 100
101 101
102 102 auto onReplyErrors = [this](QNetworkReply *reply, const QList<QSslError> &errors) {
103
104 103 qCCritical(LOG_NetworkController()) << tr("NetworkAcessManager errors: ") << errors;
105 104
106 105 };
107 106
108 107
109 108 connect(impl->m_AccessManager.get(), &QNetworkAccessManager::sslErrors, this, onReplyErrors);
110 109
111 110 qCDebug(LOG_NetworkController()) << tr("NetworkController init END");
112 111 }
113 112
114 113 void NetworkController::finalize()
115 114 {
116 115 impl->m_WorkingMutex.unlock();
117 116 }
118 117
119 118 void NetworkController::onReplyCanceled(QUuid identifier)
120 119 {
121 120 auto findReply = [identifier](const auto &entry) { return identifier == entry.second; };
122 121 qCDebug(LOG_NetworkController()) << tr("NetworkController onReplyCanceled")
123 << QThread::currentThread() << identifier;
122 << QThread::currentThread() << identifier;
124 123
125 124
126 125 impl->lockRead();
127 126 auto end = impl->m_NetworkReplyToId.cend();
128 127 auto it = std::find_if(impl->m_NetworkReplyToId.cbegin(), end, findReply);
129 128 impl->unlock();
130 129 if (it != end) {
131 130 qCDebug(LOG_NetworkController()) << tr("NetworkController onReplyCanceled ABORT DONE")
132 << QThread::currentThread() << identifier;
131 << QThread::currentThread() << identifier;
133 132 it->first->abort();
134 133 }
135 134 qCDebug(LOG_NetworkController()) << tr("NetworkController onReplyCanceled END")
136 << QThread::currentThread();
135 << QThread::currentThread();
137 136 }
138 137
139 138 void NetworkController::waitForFinish()
140 139 {
141 140 QMutexLocker locker{&impl->m_WorkingMutex};
142 141 }
General Comments 2
You need to be logged in to leave comments. Login now