##// END OF EJS Templates
Fix progression bug when aborting a request for Amda plugin
perrinel -
r701:87c4dffdd5b8
parent child
Show More
@@ -1,321 +1,300
1 1 #include "Variable/VariableAcquisitionWorker.h"
2 2
3 3 #include "Variable/Variable.h"
4 4
5 5 #include <Data/AcquisitionRequest.h>
6 6 #include <Data/SqpRange.h>
7 7
8 8 #include <unordered_map>
9 9 #include <utility>
10 10
11 11 #include <QMutex>
12 12 #include <QReadWriteLock>
13 13 #include <QThread>
14 14
15 15 #include <cmath>
16 16
17 17 Q_LOGGING_CATEGORY(LOG_VariableAcquisitionWorker, "VariableAcquisitionWorker")
18 18
19 19 struct VariableAcquisitionWorker::VariableAcquisitionWorkerPrivate {
20 20
21 21 explicit VariableAcquisitionWorkerPrivate(VariableAcquisitionWorker *parent)
22 22 : m_Lock{QReadWriteLock::Recursive}, q{parent}
23 23 {
24 24 }
25 25
26 26 void lockRead() { m_Lock.lockForRead(); }
27 27 void lockWrite() { m_Lock.lockForWrite(); }
28 28 void unlock() { m_Lock.unlock(); }
29 29
30 30 void removeVariableRequest(QUuid vIdentifier);
31 31
32 32 /// Remove the current request and execute the next one if exist
33 33 void updateToNextRequest(QUuid vIdentifier);
34 34
35 35 QMutex m_WorkingMutex;
36 36 QReadWriteLock m_Lock;
37 37
38 38 std::map<QUuid, QVector<AcquisitionDataPacket> > m_AcqIdentifierToAcqDataPacketVectorMap;
39 39 std::map<QUuid, AcquisitionRequest> m_AcqIdentifierToAcqRequestMap;
40 40 std::map<QUuid, std::pair<QUuid, QUuid> > m_VIdentifierToCurrrentAcqIdNextIdPairMap;
41 41 VariableAcquisitionWorker *q;
42 42 };
43 43
44 44
45 45 VariableAcquisitionWorker::VariableAcquisitionWorker(QObject *parent)
46 46 : QObject{parent}, impl{spimpl::make_unique_impl<VariableAcquisitionWorkerPrivate>(this)}
47 47 {
48 48 }
49 49
50 50 VariableAcquisitionWorker::~VariableAcquisitionWorker()
51 51 {
52 52 qCInfo(LOG_VariableAcquisitionWorker()) << tr("VariableAcquisitionWorker destruction")
53 53 << QThread::currentThread();
54 54 this->waitForFinish();
55 55 }
56 56
57 57
58 58 QUuid VariableAcquisitionWorker::pushVariableRequest(QUuid varRequestId, QUuid vIdentifier,
59 59 SqpRange rangeRequested,
60 60 SqpRange cacheRangeRequested,
61 61 DataProviderParameters parameters,
62 62 std::shared_ptr<IDataProvider> provider)
63 63 {
64 64 qCDebug(LOG_VariableAcquisitionWorker())
65 65 << tr("TORM VariableAcquisitionWorker::pushVariableRequest ") << cacheRangeRequested;
66 66 auto varRequestIdCanceled = QUuid();
67 67
68 68 // Request creation
69 69 auto acqRequest = AcquisitionRequest{};
70 70 acqRequest.m_VarRequestId = varRequestId;
71 71 acqRequest.m_vIdentifier = vIdentifier;
72 72 acqRequest.m_DataProviderParameters = parameters;
73 73 acqRequest.m_RangeRequested = rangeRequested;
74 74 acqRequest.m_CacheRangeRequested = cacheRangeRequested;
75 75 acqRequest.m_Size = parameters.m_Times.size();
76 76 acqRequest.m_Provider = provider;
77 77
78 78
79 79 // Register request
80 80 impl->lockWrite();
81 81 impl->m_AcqIdentifierToAcqRequestMap.insert(
82 82 std::make_pair(acqRequest.m_AcqIdentifier, acqRequest));
83 83
84 84 auto it = impl->m_VIdentifierToCurrrentAcqIdNextIdPairMap.find(vIdentifier);
85 85 if (it != impl->m_VIdentifierToCurrrentAcqIdNextIdPairMap.cend()) {
86 86 // A current request already exists, we can replace the next one
87 87 auto nextAcqId = it->second.second;
88 88 auto acqIdentifierToAcqRequestMapIt = impl->m_AcqIdentifierToAcqRequestMap.find(nextAcqId);
89 89 if (acqIdentifierToAcqRequestMapIt != impl->m_AcqIdentifierToAcqRequestMap.cend()) {
90 90 auto request = acqIdentifierToAcqRequestMapIt->second;
91 91 varRequestIdCanceled = request.m_VarRequestId;
92 92 }
93 93
94 94 it->second.second = acqRequest.m_AcqIdentifier;
95 95 impl->unlock();
96 96 }
97 97 else {
98 98 // First request for the variable, it must be stored and executed
99 99 impl->m_VIdentifierToCurrrentAcqIdNextIdPairMap.insert(
100 100 std::make_pair(vIdentifier, std::make_pair(acqRequest.m_AcqIdentifier, QUuid())));
101 101 impl->unlock();
102 102
103 103 QMetaObject::invokeMethod(this, "onExecuteRequest", Qt::QueuedConnection,
104 104 Q_ARG(QUuid, acqRequest.m_AcqIdentifier));
105 105 }
106 106
107 107 return varRequestIdCanceled;
108 108 }
109 109
110 110 void VariableAcquisitionWorker::abortProgressRequested(QUuid vIdentifier)
111 111 {
112 // TODO
113 112 impl->lockRead();
114 113
115 114 auto it = impl->m_VIdentifierToCurrrentAcqIdNextIdPairMap.find(vIdentifier);
116 115 if (it != impl->m_VIdentifierToCurrrentAcqIdNextIdPairMap.cend()) {
117 116 auto currentAcqId = it->second.first;
118 117
119 118 auto it = impl->m_AcqIdentifierToAcqRequestMap.find(currentAcqId);
120 119 if (it != impl->m_AcqIdentifierToAcqRequestMap.cend()) {
121 120 auto request = it->second;
122 121 impl->unlock();
123 122
124 123 // Remove the current request from the worker
125 124
126 125 impl->lockWrite();
127 126 impl->updateToNextRequest(vIdentifier);
128 127 impl->unlock();
129 128
130 129 // notify the request aborting to the provider
131 130 request.m_Provider->requestDataAborting(currentAcqId);
132 131 }
133 132 else {
134 133 impl->unlock();
135 134 qCWarning(LOG_VariableAcquisitionWorker())
136 135 << tr("Impossible to abort an unknown acquisition request") << currentAcqId;
137 136 }
138 137 }
139 138 else {
140 139 impl->unlock();
141 140 }
142 141 }
143 142
144 143 void VariableAcquisitionWorker::onVariableRetrieveDataInProgress(QUuid acqIdentifier,
145 144 double progress)
146 145 {
146 qCDebug(LOG_VariableAcquisitionWorker()) << tr("TORM: onVariableRetrieveDataInProgress ")
147 << acqIdentifier << progress;
147 148 impl->lockRead();
148 149 auto aIdToARit = impl->m_AcqIdentifierToAcqRequestMap.find(acqIdentifier);
149 150 if (aIdToARit != impl->m_AcqIdentifierToAcqRequestMap.cend()) {
150 151 auto currentPartSize = (aIdToARit->second.m_Size != 0) ? 100 / aIdToARit->second.m_Size : 0;
151 152
152 153 auto currentPartProgress
153 154 = std::isnan(progress) ? 0.0 : (progress * currentPartSize) / 100.0;
154 155 auto currentAlreadyProgress = aIdToARit->second.m_Progression * currentPartSize;
155 156
156 157 auto finalProgression = currentAlreadyProgress + currentPartProgress;
157 158 emit variableRequestInProgress(aIdToARit->second.m_vIdentifier, finalProgression);
158
159 qCDebug(LOG_VariableAcquisitionWorker())
160 << tr("TORM: onVariableRetrieveDataInProgress ") << aIdToARit->second.m_vIdentifier
161 << currentPartSize << currentAlreadyProgress << currentPartProgress << finalProgression;
159 162 if (finalProgression == 100.0) {
160 163 emit variableRequestInProgress(aIdToARit->second.m_vIdentifier, 0.0);
161 164 }
162 165 }
163 166 impl->unlock();
164 167 }
165 168
166 169 void VariableAcquisitionWorker::onVariableDataAcquired(QUuid acqIdentifier,
167 170 std::shared_ptr<IDataSeries> dataSeries,
168 171 SqpRange dataRangeAcquired)
169 172 {
170 173 qCDebug(LOG_VariableAcquisitionWorker()) << tr("TORM: onVariableDataAcquired on range ")
171 174 << acqIdentifier << dataRangeAcquired;
172 175 impl->lockWrite();
173 176 auto aIdToARit = impl->m_AcqIdentifierToAcqRequestMap.find(acqIdentifier);
174 177 if (aIdToARit != impl->m_AcqIdentifierToAcqRequestMap.cend()) {
175 178 // Store the result
176 179 auto dataPacket = AcquisitionDataPacket{};
177 180 dataPacket.m_Range = dataRangeAcquired;
178 181 dataPacket.m_DateSeries = dataSeries;
179 182
180 183 auto aIdToADPVit = impl->m_AcqIdentifierToAcqDataPacketVectorMap.find(acqIdentifier);
181 184 if (aIdToADPVit != impl->m_AcqIdentifierToAcqDataPacketVectorMap.cend()) {
182 185 // A current request result already exists, we can update it
183 186 aIdToADPVit->second.push_back(dataPacket);
184 187 }
185 188 else {
186 189 // First request result for the variable, it must be stored
187 190 impl->m_AcqIdentifierToAcqDataPacketVectorMap.insert(
188 191 std::make_pair(acqIdentifier, QVector<AcquisitionDataPacket>() << dataPacket));
189 192 }
190 193
191 194
192 195 // Decrement the counter of the request
193 196 auto &acqRequest = aIdToARit->second;
194 197 acqRequest.m_Progression = acqRequest.m_Progression + 1;
195 198
196 199 // if the counter is 0, we can return data then run the next request if it exists and
197 200 // removed the finished request
198 201 if (acqRequest.m_Size == acqRequest.m_Progression) {
199 202 // Return the data
200 203 aIdToADPVit = impl->m_AcqIdentifierToAcqDataPacketVectorMap.find(acqIdentifier);
201 204 if (aIdToADPVit != impl->m_AcqIdentifierToAcqDataPacketVectorMap.cend()) {
202 205 emit dataProvided(acqRequest.m_vIdentifier, acqRequest.m_RangeRequested,
203 206 acqRequest.m_CacheRangeRequested, aIdToADPVit->second);
204 207 }
205 208
206 // Execute the next one
207 auto it
208 = impl->m_VIdentifierToCurrrentAcqIdNextIdPairMap.find(acqRequest.m_vIdentifier);
209
210 if (it != impl->m_VIdentifierToCurrrentAcqIdNextIdPairMap.cend()) {
211 if (it->second.second.isNull()) {
212 // There is no next request, we can remove the variable request
213 impl->removeVariableRequest(acqRequest.m_vIdentifier);
214 }
215 else {
216 auto acqIdentifierToRemove = it->second.first;
217 // Move the next request to the current request
218 it->second.first = it->second.second;
219 it->second.second = QUuid();
220 // Remove AcquisitionRequest and results;
221 impl->m_AcqIdentifierToAcqRequestMap.erase(acqIdentifierToRemove);
222 impl->m_AcqIdentifierToAcqDataPacketVectorMap.erase(acqIdentifierToRemove);
223 // Execute the current request
224 QMetaObject::invokeMethod(this, "onExecuteRequest", Qt::QueuedConnection,
225 Q_ARG(QUuid, it->second.first));
226 }
227 }
228 else {
229 qCCritical(LOG_VariableAcquisitionWorker())
230 << tr("Impossible to execute the acquisition on an unfound variable ");
231 }
209 // Update to the next request
210 impl->updateToNextRequest(acqRequest.m_vIdentifier);
232 211 }
233 212 }
234 213 else {
235 214 qCWarning(LOG_VariableAcquisitionWorker())
236 215 << tr("Impossible to retrieve AcquisitionRequest for the incoming data.");
237 216 }
238 217 impl->unlock();
239 218 }
240 219
241 220 void VariableAcquisitionWorker::onExecuteRequest(QUuid acqIdentifier)
242 221 {
243 222 qCDebug(LOG_VariableAcquisitionWorker()) << tr("onExecuteRequest") << QThread::currentThread();
244 223 impl->lockRead();
245 224 auto it = impl->m_AcqIdentifierToAcqRequestMap.find(acqIdentifier);
246 225 if (it != impl->m_AcqIdentifierToAcqRequestMap.cend()) {
247 226 auto request = it->second;
248 227 impl->unlock();
249 228 emit variableRequestInProgress(request.m_vIdentifier, 0.1);
250 229 request.m_Provider->requestDataLoading(acqIdentifier, request.m_DataProviderParameters);
251 230 }
252 231 else {
253 232 impl->unlock();
254 233 // TODO log no acqIdentifier recognized
255 234 }
256 235 }
257 236
258 237 void VariableAcquisitionWorker::initialize()
259 238 {
260 239 qCDebug(LOG_VariableAcquisitionWorker()) << tr("VariableAcquisitionWorker init")
261 240 << QThread::currentThread();
262 241 impl->m_WorkingMutex.lock();
263 242 qCDebug(LOG_VariableAcquisitionWorker()) << tr("VariableAcquisitionWorker init END");
264 243 }
265 244
266 245 void VariableAcquisitionWorker::finalize()
267 246 {
268 247 impl->m_WorkingMutex.unlock();
269 248 }
270 249
271 250 void VariableAcquisitionWorker::waitForFinish()
272 251 {
273 252 QMutexLocker locker{&impl->m_WorkingMutex};
274 253 }
275 254
276 255 void VariableAcquisitionWorker::VariableAcquisitionWorkerPrivate::removeVariableRequest(
277 256 QUuid vIdentifier)
278 257 {
279 258 lockWrite();
280 259 auto it = m_VIdentifierToCurrrentAcqIdNextIdPairMap.find(vIdentifier);
281 260
282 261 if (it != m_VIdentifierToCurrrentAcqIdNextIdPairMap.cend()) {
283 262 // A current request already exists, we can replace the next one
284 263
285 264 m_AcqIdentifierToAcqRequestMap.erase(it->second.first);
286 265 m_AcqIdentifierToAcqDataPacketVectorMap.erase(it->second.first);
287 266
288 267 m_AcqIdentifierToAcqRequestMap.erase(it->second.second);
289 268 m_AcqIdentifierToAcqDataPacketVectorMap.erase(it->second.second);
290 269 }
291 270 m_VIdentifierToCurrrentAcqIdNextIdPairMap.erase(vIdentifier);
292 271 unlock();
293 272 }
294 273
295 274 void VariableAcquisitionWorker::VariableAcquisitionWorkerPrivate::updateToNextRequest(
296 275 QUuid vIdentifier)
297 276 {
298 277 auto it = m_VIdentifierToCurrrentAcqIdNextIdPairMap.find(vIdentifier);
299 278 if (it != m_VIdentifierToCurrrentAcqIdNextIdPairMap.cend()) {
300 279 if (it->second.second.isNull()) {
301 280 // There is no next request, we can remove the variable request
302 281 removeVariableRequest(vIdentifier);
303 282 }
304 283 else {
305 284 auto acqIdentifierToRemove = it->second.first;
306 285 // Move the next request to the current request
307 286 it->second.first = it->second.second;
308 287 it->second.second = QUuid();
309 288 // Remove AcquisitionRequest and results;
310 289 m_AcqIdentifierToAcqRequestMap.erase(acqIdentifierToRemove);
311 290 m_AcqIdentifierToAcqDataPacketVectorMap.erase(acqIdentifierToRemove);
312 291 // Execute the current request
313 292 QMetaObject::invokeMethod(q, "onExecuteRequest", Qt::QueuedConnection,
314 293 Q_ARG(QUuid, it->second.first));
315 294 }
316 295 }
317 296 else {
318 297 qCCritical(LOG_VariableAcquisitionWorker())
319 298 << tr("Impossible to execute the acquisition on an unfound variable ");
320 299 }
321 300 }
@@ -1,265 +1,274
1 1 #include "AmdaProvider.h"
2 2 #include "AmdaDefs.h"
3 3 #include "AmdaResultParser.h"
4 4
5 5 #include <Common/DateUtils.h>
6 6 #include <Data/DataProviderParameters.h>
7 7 #include <Network/NetworkController.h>
8 8 #include <SqpApplication.h>
9 9 #include <Variable/Variable.h>
10 10
11 11 #include <QNetworkAccessManager>
12 12 #include <QNetworkReply>
13 13 #include <QTemporaryFile>
14 14 #include <QThread>
15 15
16 16 Q_LOGGING_CATEGORY(LOG_AmdaProvider, "AmdaProvider")
17 17
18 18 namespace {
19 19
20 20 /// URL format for a request on AMDA server. The parameters are as follows:
21 21 /// - %1: start date
22 22 /// - %2: end date
23 23 /// - %3: parameter id
24 24 const auto AMDA_URL_FORMAT = QStringLiteral(
25 25 "http://amda.irap.omp.eu/php/rest/"
26 26 "getParameter.php?startTime=%1&stopTime=%2&parameterID=%3&outputFormat=ASCII&"
27 27 "timeFormat=ISO8601&gzip=0");
28 28
29 29 /// Dates format passed in the URL (e.g 2013-09-23T09:00)
30 30 const auto AMDA_TIME_FORMAT = QStringLiteral("yyyy-MM-ddThh:mm:ss");
31 31
32 32 /// Formats a time to a date that can be passed in URL
33 33 QString dateFormat(double sqpRange) noexcept
34 34 {
35 35 auto dateTime = DateUtils::dateTime(sqpRange);
36 36 return dateTime.toString(AMDA_TIME_FORMAT);
37 37 }
38 38
39 39 AmdaResultParser::ValueType valueType(const QString &valueType)
40 40 {
41 41 if (valueType == QStringLiteral("scalar")) {
42 42 return AmdaResultParser::ValueType::SCALAR;
43 43 }
44 44 else if (valueType == QStringLiteral("vector")) {
45 45 return AmdaResultParser::ValueType::VECTOR;
46 46 }
47 47 else {
48 48 return AmdaResultParser::ValueType::UNKNOWN;
49 49 }
50 50 }
51 51
52 52 } // namespace
53 53
54 54 AmdaProvider::AmdaProvider()
55 55 {
56 56 qCDebug(LOG_AmdaProvider()) << tr("AmdaProvider::AmdaProvider") << QThread::currentThread();
57 57 if (auto app = sqpApp) {
58 58 auto &networkController = app->networkController();
59 59 connect(this, SIGNAL(requestConstructed(std::shared_ptr<QNetworkRequest>, QUuid,
60 60 std::function<void(QNetworkReply *, QUuid)>)),
61 61 &networkController,
62 62 SLOT(onProcessRequested(std::shared_ptr<QNetworkRequest>, QUuid,
63 63 std::function<void(QNetworkReply *, QUuid)>)));
64 64
65 65
66 66 connect(&sqpApp->networkController(),
67 67 SIGNAL(replyDownloadProgress(QUuid, std::shared_ptr<QNetworkRequest>, double)),
68 68 this,
69 69 SLOT(onReplyDownloadProgress(QUuid, std::shared_ptr<QNetworkRequest>, double)));
70 70 }
71 71 }
72 72
73 73 std::shared_ptr<IDataProvider> AmdaProvider::clone() const
74 74 {
75 75 // No copy is made in the clone
76 76 return std::make_shared<AmdaProvider>();
77 77 }
78 78
79 79 void AmdaProvider::requestDataLoading(QUuid acqIdentifier, const DataProviderParameters &parameters)
80 80 {
81 81 // NOTE: Try to use multithread if possible
82 82 const auto times = parameters.m_Times;
83 83 const auto data = parameters.m_Data;
84 84 for (const auto &dateTime : qAsConst(times)) {
85 85 this->retrieveData(acqIdentifier, dateTime, data);
86 86
87 87
88 88 // TORM when AMDA will support quick asynchrone request
89 89 QThread::msleep(1000);
90 90 }
91 91 }
92 92
93 93 void AmdaProvider::requestDataAborting(QUuid acqIdentifier)
94 94 {
95 95 if (auto app = sqpApp) {
96 96 auto &networkController = app->networkController();
97 97 networkController.onReplyCanceled(acqIdentifier);
98 98 }
99 99 }
100 100
101 101 void AmdaProvider::onReplyDownloadProgress(QUuid acqIdentifier,
102 102 std::shared_ptr<QNetworkRequest> networkRequest,
103 103 double progress)
104 104 {
105 qCDebug(LOG_AmdaProvider()) << tr("onReplyDownloadProgress") << acqIdentifier
106 << networkRequest.get() << progress;
105 qCInfo(LOG_AmdaProvider()) << tr("onReplyDownloadProgress") << acqIdentifier
106 << networkRequest.get() << progress;
107 107 auto acqIdToRequestProgressMapIt = m_AcqIdToRequestProgressMap.find(acqIdentifier);
108 108 if (acqIdToRequestProgressMapIt != m_AcqIdToRequestProgressMap.end()) {
109 109
110 110 auto requestPtr = networkRequest;
111 111 auto findRequest = [requestPtr](const auto &entry) { return requestPtr == entry.first; };
112 112
113 113 auto &requestProgressMap = acqIdToRequestProgressMapIt->second;
114 114 auto requestProgressMapEnd = requestProgressMap.end();
115 115 auto requestProgressMapIt
116 116 = std::find_if(requestProgressMap.begin(), requestProgressMapEnd, findRequest);
117 117
118 118 if (requestProgressMapIt != requestProgressMapEnd) {
119 119 requestProgressMapIt->second = progress;
120 120 }
121 121 else {
122 qCCritical(LOG_AmdaProvider()) << tr("Can't retrieve Request in progress")
123 << acqIdentifier << networkRequest.get() << progress;
122 // This case can happened when a progression is send after the request has been
123 // finished.
124 // Generaly the case when aborting a request
125 qCWarning(LOG_AmdaProvider()) << tr("Can't retrieve Request in progress")
126 << acqIdentifier << networkRequest.get() << progress;
124 127 }
125 128 }
126 129
127 130 acqIdToRequestProgressMapIt = m_AcqIdToRequestProgressMap.find(acqIdentifier);
128 131 if (acqIdToRequestProgressMapIt != m_AcqIdToRequestProgressMap.end()) {
129 132 double finalProgress = 0.0;
130 133
131 134 auto &requestProgressMap = acqIdToRequestProgressMapIt->second;
132 135 auto fraq = requestProgressMap.size();
133 136
134 137 for (auto requestProgress : requestProgressMap) {
135 138 finalProgress += requestProgress.second;
136 139 qCDebug(LOG_AmdaProvider()) << tr("current final progress without freq:")
137 140 << finalProgress << requestProgress.second;
138 141 }
139 142
140 143 if (fraq > 0) {
141 144 finalProgress = finalProgress / fraq;
142 145 }
143 146
144 147 qCDebug(LOG_AmdaProvider()) << tr("2 onReplyDownloadProgress final progress") << fraq
145 148 << finalProgress;
146 149 emit dataProvidedProgress(acqIdentifier, finalProgress);
147 150 }
148 151 else {
149 emit dataProvidedProgress(acqIdentifier, 0.0);
152 // This case can happened when a progression is send after the request has been finished.
153 // Generaly the case when aborting a request
154 emit dataProvidedProgress(acqIdentifier, 100.0);
150 155 }
151 156 }
152 157
153 158 void AmdaProvider::retrieveData(QUuid token, const SqpRange &dateTime, const QVariantHash &data)
154 159 {
155 160 // Retrieves product ID from data: if the value is invalid, no request is made
156 161 auto productId = data.value(AMDA_XML_ID_KEY).toString();
157 162 if (productId.isNull()) {
158 163 qCCritical(LOG_AmdaProvider()) << tr("Can't retrieve data: unknown product id");
159 164 return;
160 165 }
161 166
162 167 // Retrieves the data type that determines whether the expected format for the result file is
163 168 // scalar, vector...
164 169 auto productValueType = valueType(data.value(AMDA_DATA_TYPE_KEY).toString());
165 170
166 171 // /////////// //
167 172 // Creates URL //
168 173 // /////////// //
169 174
170 175 auto startDate = dateFormat(dateTime.m_TStart);
171 176 auto endDate = dateFormat(dateTime.m_TEnd);
172 177
173 178 auto url = QUrl{QString{AMDA_URL_FORMAT}.arg(startDate, endDate, productId)};
174 179 qCDebug(LOG_AmdaProvider()) << tr("TORM AmdaProvider::retrieveData url:") << url;
175 180 auto tempFile = std::make_shared<QTemporaryFile>();
176 181
177 182 // LAMBDA
178 183 auto httpDownloadFinished = [this, dateTime, tempFile,
179 184 productValueType](QNetworkReply *reply, QUuid dataId) noexcept {
180 185
181 186 // Don't do anything if the reply was abort
182 187 if (reply->error() != QNetworkReply::OperationCanceledError) {
183 188
184 189 if (tempFile) {
185 190 auto replyReadAll = reply->readAll();
186 191 if (!replyReadAll.isEmpty()) {
187 192 tempFile->write(replyReadAll);
188 193 }
189 194 tempFile->close();
190 195
191 196 // Parse results file
192 197 if (auto dataSeries
193 198 = AmdaResultParser::readTxt(tempFile->fileName(), productValueType)) {
194 199 emit dataProvided(dataId, dataSeries, dateTime);
195 200 }
196 201 else {
197 202 /// @todo ALX : debug
198 203 }
199 204 }
205 qCDebug(LOG_AmdaProvider()) << tr("acquisition requests erase because of finishing")
206 << dataId;
200 207 m_AcqIdToRequestProgressMap.erase(dataId);
201 208 }
202 209
203 210 };
204 211 auto httpFinishedLambda
205 212 = [this, httpDownloadFinished, tempFile](QNetworkReply *reply, QUuid dataId) noexcept {
206 213
207 214 // Don't do anything if the reply was abort
208 215 if (reply->error() != QNetworkReply::OperationCanceledError) {
209 216 auto downloadFileUrl = QUrl{QString{reply->readAll()}};
210 217
211 218 qCDebug(LOG_AmdaProvider())
212 219 << tr("TORM AmdaProvider::retrieveData downloadFileUrl:") << downloadFileUrl;
213 220 // Executes request for downloading file //
214 221
215 222 // Creates destination file
216 223 if (tempFile->open()) {
217 224 // Executes request and store the request for progression
218 225 auto request = std::make_shared<QNetworkRequest>(downloadFileUrl);
219 226 updateRequestProgress(dataId, request, 0.0);
220 227 emit requestConstructed(request, dataId, httpDownloadFinished);
221 228 }
222 229 }
223 230 else {
231 qCDebug(LOG_AmdaProvider())
232 << tr("acquisition requests erase because of aborting") << dataId;
224 233 m_AcqIdToRequestProgressMap.erase(dataId);
225 234 }
226 235 };
227 236
228 237 // //////////////// //
229 238 // Executes request //
230 239 // //////////////// //
231 240
232 241 auto request = std::make_shared<QNetworkRequest>(url);
233 242 qCDebug(LOG_AmdaProvider()) << tr("First Request creation") << request.get();
234 243 updateRequestProgress(token, request, 0.0);
235 244
236 245 emit requestConstructed(request, token, httpFinishedLambda);
237 246 }
238 247
239 248 void AmdaProvider::updateRequestProgress(QUuid acqIdentifier,
240 249 std::shared_ptr<QNetworkRequest> request, double progress)
241 250 {
242 251 auto acqIdToRequestProgressMapIt = m_AcqIdToRequestProgressMap.find(acqIdentifier);
243 252 if (acqIdToRequestProgressMapIt != m_AcqIdToRequestProgressMap.end()) {
244 253 auto &requestProgressMap = acqIdToRequestProgressMapIt->second;
245 254 auto requestProgressMapIt = requestProgressMap.find(request);
246 255 if (requestProgressMapIt != requestProgressMap.end()) {
247 256 requestProgressMapIt->second = progress;
248 257 qCDebug(LOG_AmdaProvider()) << tr("updateRequestProgress new progress for request")
249 258 << acqIdentifier << request.get() << progress;
250 259 }
251 260 else {
252 261 qCDebug(LOG_AmdaProvider()) << tr("updateRequestProgress new request") << acqIdentifier
253 262 << request.get() << progress;
254 263 acqIdToRequestProgressMapIt->second.insert(std::make_pair(request, progress));
255 264 }
256 265 }
257 266 else {
258 267 qCDebug(LOG_AmdaProvider()) << tr("updateRequestProgress new acqIdentifier")
259 268 << acqIdentifier << request.get() << progress;
260 269 auto requestProgressMap = std::map<std::shared_ptr<QNetworkRequest>, double>{};
261 270 requestProgressMap.insert(std::make_pair(request, progress));
262 271 m_AcqIdToRequestProgressMap.insert(
263 272 std::make_pair(acqIdentifier, std::move(requestProgressMap)));
264 273 }
265 274 }
General Comments 2
You need to be logged in to leave comments. Login now