From b7833b9d2064fa480d3f95355b225b117f5ce4d5 2017-09-22 07:53:24 From: leroux Date: 2017-09-22 07:53:24 Subject: [PATCH] Merge pull request #290 from SCIQLOP-Initialisation develop Develop --- diff --git a/core/include/Data/AcquisitionRequest.h b/core/include/Data/AcquisitionRequest.h index d9d338a..9e2b0de 100644 --- a/core/include/Data/AcquisitionRequest.h +++ b/core/include/Data/AcquisitionRequest.h @@ -21,6 +21,7 @@ struct AcquisitionRequest { { m_AcqIdentifier = QUuid::createUuid(); m_Size = 0; + m_Progression = 0; } QUuid m_VarRequestId; @@ -30,6 +31,7 @@ struct AcquisitionRequest { SqpRange m_RangeRequested; SqpRange m_CacheRangeRequested; int m_Size; + int m_Progression; std::shared_ptr m_Provider; }; diff --git a/core/include/Data/IDataProvider.h b/core/include/Data/IDataProvider.h index 55dd069..6ff3b18 100644 --- a/core/include/Data/IDataProvider.h +++ b/core/include/Data/IDataProvider.h @@ -55,17 +55,21 @@ signals: const SqpRange &dataRangeAcquired); /** - * @brief dataProvided send dataSeries under dateTime and that corresponds of the data - * identified by identifier - */ + * @brief dataProvidedProgress notify the progression of the data identifier by acqIdentifier + */ void dataProvidedProgress(QUuid acqIdentifier, double progress); + /** + * @brief dataProvidedFailed notify that data acquisition has failed + */ + void dataProvidedFailed(QUuid acqIdentifier); + /** * @brief requestConstructed send a request for the data identified by acqIdentifier * @callback is the methode call by the reply of the request when it is finished. */ - void requestConstructed(const QNetworkRequest &request, QUuid acqIdentifier, + void requestConstructed(std::shared_ptr request, QUuid acqIdentifier, std::function callback); }; diff --git a/core/include/Network/NetworkController.h b/core/include/Network/NetworkController.h index ca19b89..da3a2c5 100644 --- a/core/include/Network/NetworkController.h +++ b/core/include/Network/NetworkController.h @@ -7,6 +7,7 @@ #include #include +#include #include #include @@ -29,14 +30,15 @@ public: public slots: /// Execute request and call callback when the reply is finished. Identifier is attached to the /// callback - void onProcessRequested(const QNetworkRequest &request, QUuid identifier, + void onProcessRequested(std::shared_ptr request, QUuid identifier, std::function callback); /// Cancel the request of identifier void onReplyCanceled(QUuid identifier); signals: void replyFinished(QNetworkReply *reply, QUuid identifier); - void replyDownloadProgress(QUuid identifier, double progress); + void replyDownloadProgress(QUuid identifier, std::shared_ptr networkRequest, + double progress); private: void waitForFinish(); @@ -45,4 +47,7 @@ private: spimpl::unique_impl_ptr impl; }; +SCIQLOP_REGISTER_META_TYPE(NETWORKREQUEST_REGISTRY, std::shared_ptr) + + #endif // SCIQLOP_NETWORKCONTROLLER_H diff --git a/core/include/Variable/Variable.h b/core/include/Variable/Variable.h index eb9b144..bf30f18 100644 --- a/core/include/Variable/Variable.h +++ b/core/include/Variable/Variable.h @@ -25,8 +25,7 @@ class SCIQLOP_CORE_EXPORT Variable : public QObject { Q_OBJECT public: - explicit Variable(const QString &name, const SqpRange &dateTime, - const QVariantHash &metadata = {}); + explicit Variable(const QString &name, const QVariantHash &metadata = {}); /// Copy ctor explicit Variable(const Variable &other); diff --git a/core/include/Variable/VariableAcquisitionWorker.h b/core/include/Variable/VariableAcquisitionWorker.h index 25f7f0b..f5badbc 100644 --- a/core/include/Variable/VariableAcquisitionWorker.h +++ b/core/include/Variable/VariableAcquisitionWorker.h @@ -43,10 +43,15 @@ signals: void variableRequestInProgress(QUuid vIdentifier, double progress); + + void variableCanceledRequested(QUuid vIdentifier); + + public slots: void onVariableDataAcquired(QUuid acqIdentifier, std::shared_ptr dataSeries, SqpRange dataRangeAcquired); void onVariableRetrieveDataInProgress(QUuid acqIdentifier, double progress); + void onVariableAcquisitionFailed(QUuid acqIdentifier); private: void waitForFinish(); diff --git a/core/include/Variable/VariableController.h b/core/include/Variable/VariableController.h index 1fd9c9c..b016617 100644 --- a/core/include/Variable/VariableController.h +++ b/core/include/Variable/VariableController.h @@ -68,10 +68,6 @@ public: */ void deleteVariables(const QVector > &variables) noexcept; - /** - * @brief abort the variable retrieve data progression - */ - void abortProgress(std::shared_ptr variable); static AcquisitionZoomType getZoomType(const SqpRange &range, const SqpRange &oldRange); signals: @@ -110,6 +106,7 @@ public slots: /// Cancel the current request for the variable void onAbortProgressRequested(std::shared_ptr variable); + void onAbortAcquisitionRequested(QUuid vIdentifier); // synchronization group methods void onAddSynchronizationGroupId(QUuid synchronizationGroupId); diff --git a/core/include/Variable/VariableModel.h b/core/include/Variable/VariableModel.h index adbcd1d..960ea81 100644 --- a/core/include/Variable/VariableModel.h +++ b/core/include/Variable/VariableModel.h @@ -45,11 +45,10 @@ public: /** * Creates a new variable in the model * @param name the name of the new variable - * @param dateTime the dateTime of the new variable * @param metadata the metadata associated to the new variable * @return the pointer to the new variable */ - std::shared_ptr createVariable(const QString &name, const SqpRange &dateTime, + std::shared_ptr createVariable(const QString &name, const QVariantHash &metadata) noexcept; /** diff --git a/core/src/Network/NetworkController.cpp b/core/src/Network/NetworkController.cpp index 1649cc5..dcaacc6 100644 --- a/core/src/Network/NetworkController.cpp +++ b/core/src/Network/NetworkController.cpp @@ -21,7 +21,7 @@ struct NetworkController::NetworkControllerPrivate { QMutex m_WorkingMutex; QReadWriteLock m_Lock; - std::unordered_map m_NetworkReplyToVariableId; + std::unordered_map m_NetworkReplyToId; std::unique_ptr m_AccessManager{nullptr}; }; @@ -30,53 +30,66 @@ NetworkController::NetworkController(QObject *parent) { } -void NetworkController::onProcessRequested(const QNetworkRequest &request, QUuid identifier, +void NetworkController::onProcessRequested(std::shared_ptr request, + QUuid identifier, std::function callback) { - qCDebug(LOG_NetworkController()) << tr("NetworkController registered") - << QThread::currentThread()->objectName(); - auto reply = impl->m_AccessManager->get(request); + qCDebug(LOG_NetworkController()) << tr("NetworkController onProcessRequested") + << QThread::currentThread()->objectName() << &request; + auto reply = impl->m_AccessManager->get(*request); // Store the couple reply id impl->lockWrite(); - impl->m_NetworkReplyToVariableId[reply] = identifier; + impl->m_NetworkReplyToId[reply] = identifier; + qCDebug(LOG_NetworkController()) << tr("Store for reply: ") << identifier; impl->unlock(); - auto onReplyFinished = [reply, this, identifier, callback]() { + auto onReplyFinished = [request, reply, this, identifier, callback]() { qCDebug(LOG_NetworkController()) << tr("NetworkController onReplyFinished") - << QThread::currentThread() << reply; + << QThread::currentThread() << request.get() << reply; impl->lockRead(); - auto it = impl->m_NetworkReplyToVariableId.find(reply); - impl->unlock(); - if (it != impl->m_NetworkReplyToVariableId.cend()) { + auto it = impl->m_NetworkReplyToId.find(reply); + if (it != impl->m_NetworkReplyToId.cend()) { + qCDebug(LOG_NetworkController()) << tr("Remove for reply: ") << it->second; + impl->unlock(); impl->lockWrite(); - impl->m_NetworkReplyToVariableId.erase(reply); + impl->m_NetworkReplyToId.erase(reply); impl->unlock(); // Deletes reply callback(reply, identifier); reply->deleteLater(); - - emit this->replyDownloadProgress(identifier, 0); + } + else { + impl->unlock(); } qCDebug(LOG_NetworkController()) << tr("NetworkController onReplyFinished END") << QThread::currentThread() << reply; }; - auto onReplyProgress = [reply, this](qint64 bytesRead, qint64 totalBytes) { - - double progress = (bytesRead * 100.0) / totalBytes; - qCDebug(LOG_NetworkController()) << tr("NetworkController onReplyProgress") << progress - << QThread::currentThread() << reply; - impl->lockRead(); - auto it = impl->m_NetworkReplyToVariableId.find(reply); - impl->unlock(); - if (it != impl->m_NetworkReplyToVariableId.cend()) { - emit this->replyDownloadProgress(it->second, progress); + auto onReplyProgress = [reply, request, this](qint64 bytesRead, qint64 totalBytes) { + + // NOTE: a totalbytes of 0 can happened when a request has been aborted + if (totalBytes > 0) { + double progress = (bytesRead * 100.0) / totalBytes; + qCDebug(LOG_NetworkController()) << tr("NetworkController onReplyProgress") << progress + << QThread::currentThread() << request.get() << reply + << bytesRead << totalBytes; + impl->lockRead(); + auto it = impl->m_NetworkReplyToId.find(reply); + if (it != impl->m_NetworkReplyToId.cend()) { + auto id = it->second; + impl->unlock(); + emit this->replyDownloadProgress(id, request, progress); + } + else { + impl->unlock(); + } + + qCDebug(LOG_NetworkController()) << tr("NetworkController onReplyProgress END") + << QThread::currentThread() << reply; } - qCDebug(LOG_NetworkController()) << tr("NetworkController onReplyProgress END") - << QThread::currentThread() << reply; }; @@ -94,7 +107,6 @@ void NetworkController::initialize() auto onReplyErrors = [this](QNetworkReply *reply, const QList &errors) { - qCCritical(LOG_NetworkController()) << tr("NetworkAcessManager errors: ") << errors; }; @@ -114,14 +126,16 @@ void NetworkController::onReplyCanceled(QUuid identifier) { auto findReply = [identifier](const auto &entry) { return identifier == entry.second; }; qCDebug(LOG_NetworkController()) << tr("NetworkController onReplyCanceled") - << QThread::currentThread(); + << QThread::currentThread() << identifier; impl->lockRead(); - auto end = impl->m_NetworkReplyToVariableId.cend(); - auto it = std::find_if(impl->m_NetworkReplyToVariableId.cbegin(), end, findReply); + auto end = impl->m_NetworkReplyToId.cend(); + auto it = std::find_if(impl->m_NetworkReplyToId.cbegin(), end, findReply); impl->unlock(); if (it != end) { + qCDebug(LOG_NetworkController()) << tr("NetworkController onReplyCanceled ABORT DONE") + << QThread::currentThread() << identifier; it->first->abort(); } qCDebug(LOG_NetworkController()) << tr("NetworkController onReplyCanceled END") diff --git a/core/src/Variable/Variable.cpp b/core/src/Variable/Variable.cpp index ed9c248..988f06a 100644 --- a/core/src/Variable/Variable.cpp +++ b/core/src/Variable/Variable.cpp @@ -10,10 +10,10 @@ Q_LOGGING_CATEGORY(LOG_Variable, "Variable") struct Variable::VariablePrivate { - explicit VariablePrivate(const QString &name, const SqpRange &dateTime, - const QVariantHash &metadata) + explicit VariablePrivate(const QString &name, const QVariantHash &metadata) : m_Name{name}, - m_Range{dateTime}, + m_Range{INVALID_RANGE}, + m_CacheRange{INVALID_RANGE}, m_Metadata{metadata}, m_DataSeries{nullptr}, m_RealRange{INVALID_RANGE}, @@ -24,6 +24,7 @@ struct Variable::VariablePrivate { VariablePrivate(const VariablePrivate &other) : m_Name{other.m_Name}, m_Range{other.m_Range}, + m_CacheRange{other.m_CacheRange}, m_Metadata{other.m_Metadata}, m_DataSeries{other.m_DataSeries != nullptr ? other.m_DataSeries->clone() : nullptr}, m_RealRange{other.m_RealRange}, @@ -55,9 +56,10 @@ struct Variable::VariablePrivate { auto minXAxisIt = m_DataSeries->minXAxisData(m_Range.m_TStart); auto maxXAxisIt = m_DataSeries->maxXAxisData(m_Range.m_TEnd); - m_RealRange = (minXAxisIt != end && maxXAxisIt != end) - ? SqpRange{minXAxisIt->x(), maxXAxisIt->x()} - : INVALID_RANGE; + m_RealRange + = (minXAxisIt != end && maxXAxisIt != end && minXAxisIt->x() <= maxXAxisIt->x()) + ? SqpRange{minXAxisIt->x(), maxXAxisIt->x()} + : INVALID_RANGE; m_DataSeries->unlock(); } else { @@ -77,8 +79,8 @@ struct Variable::VariablePrivate { QReadWriteLock m_Lock; }; -Variable::Variable(const QString &name, const SqpRange &dateTime, const QVariantHash &metadata) - : impl{spimpl::make_unique_impl(name, dateTime, metadata)} +Variable::Variable(const QString &name, const QVariantHash &metadata) + : impl{spimpl::make_unique_impl(name, metadata)} { } @@ -242,31 +244,35 @@ bool Variable::cacheIsInside(const SqpRange &range) const noexcept QVector Variable::provideNotInCacheRangeList(const SqpRange &range) const noexcept { // This code assume that cach in contigue. Can return 0, 1 or 2 SqpRange - auto notInCache = QVector{}; - - if (!this->cacheContains(range)) { - if (range.m_TEnd <= impl->m_CacheRange.m_TStart - || range.m_TStart >= impl->m_CacheRange.m_TEnd) { - notInCache << range; - } - else if (range.m_TStart < impl->m_CacheRange.m_TStart - && range.m_TEnd <= impl->m_CacheRange.m_TEnd) { - notInCache << SqpRange{range.m_TStart, impl->m_CacheRange.m_TStart}; - } - else if (range.m_TStart < impl->m_CacheRange.m_TStart - && range.m_TEnd > impl->m_CacheRange.m_TEnd) { - notInCache << SqpRange{range.m_TStart, impl->m_CacheRange.m_TStart} - << SqpRange{impl->m_CacheRange.m_TEnd, range.m_TEnd}; - } - else if (range.m_TStart < impl->m_CacheRange.m_TEnd) { - notInCache << SqpRange{impl->m_CacheRange.m_TEnd, range.m_TEnd}; - } - else { - qCCritical(LOG_Variable()) << tr("Detection of unknown case.") - << QThread::currentThread(); + if (impl->m_CacheRange != INVALID_RANGE) { + + if (!this->cacheContains(range)) { + if (range.m_TEnd <= impl->m_CacheRange.m_TStart + || range.m_TStart >= impl->m_CacheRange.m_TEnd) { + notInCache << range; + } + else if (range.m_TStart < impl->m_CacheRange.m_TStart + && range.m_TEnd <= impl->m_CacheRange.m_TEnd) { + notInCache << SqpRange{range.m_TStart, impl->m_CacheRange.m_TStart}; + } + else if (range.m_TStart < impl->m_CacheRange.m_TStart + && range.m_TEnd > impl->m_CacheRange.m_TEnd) { + notInCache << SqpRange{range.m_TStart, impl->m_CacheRange.m_TStart} + << SqpRange{impl->m_CacheRange.m_TEnd, range.m_TEnd}; + } + else if (range.m_TStart < impl->m_CacheRange.m_TEnd) { + notInCache << SqpRange{impl->m_CacheRange.m_TEnd, range.m_TEnd}; + } + else { + qCCritical(LOG_Variable()) << tr("Detection of unknown case.") + << QThread::currentThread(); + } } } + else { + notInCache << range; + } return notInCache; } @@ -277,29 +283,31 @@ QVector Variable::provideInCacheRangeList(const SqpRange &range) const auto inCache = QVector{}; - - if (this->intersect(range)) { - if (range.m_TStart <= impl->m_CacheRange.m_TStart - && range.m_TEnd >= impl->m_CacheRange.m_TStart - && range.m_TEnd < impl->m_CacheRange.m_TEnd) { - inCache << SqpRange{impl->m_CacheRange.m_TStart, range.m_TEnd}; - } - - else if (range.m_TStart >= impl->m_CacheRange.m_TStart - && range.m_TEnd <= impl->m_CacheRange.m_TEnd) { - inCache << range; - } - else if (range.m_TStart > impl->m_CacheRange.m_TStart - && range.m_TEnd > impl->m_CacheRange.m_TEnd) { - inCache << SqpRange{range.m_TStart, impl->m_CacheRange.m_TEnd}; - } - else if (range.m_TStart <= impl->m_CacheRange.m_TStart - && range.m_TEnd >= impl->m_CacheRange.m_TEnd) { - inCache << impl->m_CacheRange; - } - else { - qCCritical(LOG_Variable()) << tr("Detection of unknown case.") - << QThread::currentThread(); + if (impl->m_CacheRange != INVALID_RANGE) { + + if (this->intersect(range)) { + if (range.m_TStart <= impl->m_CacheRange.m_TStart + && range.m_TEnd >= impl->m_CacheRange.m_TStart + && range.m_TEnd < impl->m_CacheRange.m_TEnd) { + inCache << SqpRange{impl->m_CacheRange.m_TStart, range.m_TEnd}; + } + + else if (range.m_TStart >= impl->m_CacheRange.m_TStart + && range.m_TEnd <= impl->m_CacheRange.m_TEnd) { + inCache << range; + } + else if (range.m_TStart > impl->m_CacheRange.m_TStart + && range.m_TEnd > impl->m_CacheRange.m_TEnd) { + inCache << SqpRange{range.m_TStart, impl->m_CacheRange.m_TEnd}; + } + else if (range.m_TStart <= impl->m_CacheRange.m_TStart + && range.m_TEnd >= impl->m_CacheRange.m_TEnd) { + inCache << impl->m_CacheRange; + } + else { + qCCritical(LOG_Variable()) << tr("Detection of unknown case.") + << QThread::currentThread(); + } } } diff --git a/core/src/Variable/VariableAcquisitionWorker.cpp b/core/src/Variable/VariableAcquisitionWorker.cpp index f24a269..5eac38c 100644 --- a/core/src/Variable/VariableAcquisitionWorker.cpp +++ b/core/src/Variable/VariableAcquisitionWorker.cpp @@ -12,11 +12,16 @@ #include #include +#include + Q_LOGGING_CATEGORY(LOG_VariableAcquisitionWorker, "VariableAcquisitionWorker") struct VariableAcquisitionWorker::VariableAcquisitionWorkerPrivate { - explicit VariableAcquisitionWorkerPrivate() : m_Lock{QReadWriteLock::Recursive} {} + explicit VariableAcquisitionWorkerPrivate(VariableAcquisitionWorker *parent) + : m_Lock{QReadWriteLock::Recursive}, q{parent} + { + } void lockRead() { m_Lock.lockForRead(); } void lockWrite() { m_Lock.lockForWrite(); } @@ -24,17 +29,21 @@ struct VariableAcquisitionWorker::VariableAcquisitionWorkerPrivate { void removeVariableRequest(QUuid vIdentifier); + /// Remove the current request and execute the next one if exist + void updateToNextRequest(QUuid vIdentifier); + QMutex m_WorkingMutex; QReadWriteLock m_Lock; std::map > m_AcqIdentifierToAcqDataPacketVectorMap; std::map m_AcqIdentifierToAcqRequestMap; std::map > m_VIdentifierToCurrrentAcqIdNextIdPairMap; + VariableAcquisitionWorker *q; }; VariableAcquisitionWorker::VariableAcquisitionWorker(QObject *parent) - : QObject{parent}, impl{spimpl::make_unique_impl()} + : QObject{parent}, impl{spimpl::make_unique_impl(this)} { } @@ -58,6 +67,7 @@ QUuid VariableAcquisitionWorker::pushVariableRequest(QUuid varRequestId, QUuid v // Request creation auto acqRequest = AcquisitionRequest{}; + qCInfo(LOG_VariableAcquisitionWorker()) << tr("TpushVariableRequest ") << vIdentifier; acqRequest.m_VarRequestId = varRequestId; acqRequest.m_vIdentifier = vIdentifier; acqRequest.m_DataProviderParameters = parameters; @@ -100,20 +110,89 @@ QUuid VariableAcquisitionWorker::pushVariableRequest(QUuid varRequestId, QUuid v void VariableAcquisitionWorker::abortProgressRequested(QUuid vIdentifier) { - // TODO + impl->lockRead(); + + auto it = impl->m_VIdentifierToCurrrentAcqIdNextIdPairMap.find(vIdentifier); + if (it != impl->m_VIdentifierToCurrrentAcqIdNextIdPairMap.cend()) { + auto currentAcqId = it->second.first; + + auto it = impl->m_AcqIdentifierToAcqRequestMap.find(currentAcqId); + if (it != impl->m_AcqIdentifierToAcqRequestMap.cend()) { + auto request = it->second; + impl->unlock(); + + // Remove the current request from the worker + + impl->lockWrite(); + impl->updateToNextRequest(vIdentifier); + impl->unlock(); + + // notify the request aborting to the provider + request.m_Provider->requestDataAborting(currentAcqId); + } + else { + impl->unlock(); + qCWarning(LOG_VariableAcquisitionWorker()) + << tr("Impossible to abort an unknown acquisition request") << currentAcqId; + } + } + else { + impl->unlock(); + } } void VariableAcquisitionWorker::onVariableRetrieveDataInProgress(QUuid acqIdentifier, double progress) { - // TODO + qCDebug(LOG_VariableAcquisitionWorker()) << tr("TORM: onVariableRetrieveDataInProgress ") + << acqIdentifier << progress; + impl->lockRead(); + auto aIdToARit = impl->m_AcqIdentifierToAcqRequestMap.find(acqIdentifier); + if (aIdToARit != impl->m_AcqIdentifierToAcqRequestMap.cend()) { + auto currentPartSize = (aIdToARit->second.m_Size != 0) ? 100 / aIdToARit->second.m_Size : 0; + + auto currentPartProgress + = std::isnan(progress) ? 0.0 : (progress * currentPartSize) / 100.0; + auto currentAlreadyProgress = aIdToARit->second.m_Progression * currentPartSize; + + auto finalProgression = currentAlreadyProgress + currentPartProgress; + emit variableRequestInProgress(aIdToARit->second.m_vIdentifier, finalProgression); + qCDebug(LOG_VariableAcquisitionWorker()) + << tr("TORM: onVariableRetrieveDataInProgress ") + << QThread::currentThread()->objectName() << aIdToARit->second.m_vIdentifier + << currentPartSize << currentAlreadyProgress << currentPartProgress << finalProgression; + if (finalProgression == 100.0) { + emit variableRequestInProgress(aIdToARit->second.m_vIdentifier, 0.0); + } + } + impl->unlock(); +} + +void VariableAcquisitionWorker::onVariableAcquisitionFailed(QUuid acqIdentifier) +{ + qCDebug(LOG_VariableAcquisitionWorker()) << tr("onVariableAcquisitionFailed") + << QThread::currentThread(); + impl->lockRead(); + auto it = impl->m_AcqIdentifierToAcqRequestMap.find(acqIdentifier); + if (it != impl->m_AcqIdentifierToAcqRequestMap.cend()) { + auto request = it->second; + impl->unlock(); + qCInfo(LOG_VariableAcquisitionWorker()) << tr("onVariableAcquisitionFailed") + << acqIdentifier << request.m_vIdentifier + << QThread::currentThread(); + emit variableCanceledRequested(request.m_vIdentifier); + } + else { + impl->unlock(); + // TODO log no acqIdentifier recognized + } } void VariableAcquisitionWorker::onVariableDataAcquired(QUuid acqIdentifier, std::shared_ptr dataSeries, SqpRange dataRangeAcquired) { - qCDebug(LOG_VariableAcquisitionWorker()) << tr("onVariableDataAcquired on range ") + qCDebug(LOG_VariableAcquisitionWorker()) << tr("TORM: onVariableDataAcquired on range ") << acqIdentifier << dataRangeAcquired; impl->lockWrite(); auto aIdToARit = impl->m_AcqIdentifierToAcqRequestMap.find(acqIdentifier); @@ -137,11 +216,11 @@ void VariableAcquisitionWorker::onVariableDataAcquired(QUuid acqIdentifier, // Decrement the counter of the request auto &acqRequest = aIdToARit->second; - acqRequest.m_Size = acqRequest.m_Size - 1; + acqRequest.m_Progression = acqRequest.m_Progression + 1; // if the counter is 0, we can return data then run the next request if it exists and // removed the finished request - if (acqRequest.m_Size == 0) { + if (acqRequest.m_Size == acqRequest.m_Progression) { // Return the data aIdToADPVit = impl->m_AcqIdentifierToAcqDataPacketVectorMap.find(acqIdentifier); if (aIdToADPVit != impl->m_AcqIdentifierToAcqDataPacketVectorMap.cend()) { @@ -149,41 +228,34 @@ void VariableAcquisitionWorker::onVariableDataAcquired(QUuid acqIdentifier, acqRequest.m_CacheRangeRequested, aIdToADPVit->second); } - // Execute the next one - auto it - = impl->m_VIdentifierToCurrrentAcqIdNextIdPairMap.find(acqRequest.m_vIdentifier); - - if (it != impl->m_VIdentifierToCurrrentAcqIdNextIdPairMap.cend()) { - if (it->second.second.isNull()) { - // There is no next request, we can remove the variable request - impl->removeVariableRequest(acqRequest.m_vIdentifier); - } - else { - auto acqIdentifierToRemove = it->second.first; - // Move the next request to the current request - it->second.first = it->second.second; - it->second.second = QUuid(); - // Remove AcquisitionRequest and results; - impl->m_AcqIdentifierToAcqRequestMap.erase(acqIdentifierToRemove); - impl->m_AcqIdentifierToAcqDataPacketVectorMap.erase(acqIdentifierToRemove); - // Execute the current request - QMetaObject::invokeMethod(this, "onExecuteRequest", Qt::QueuedConnection, - Q_ARG(QUuid, it->second.first)); - } - } - else { - qCCritical(LOG_VariableAcquisitionWorker()) - << tr("Impossible to execute the acquisition on an unfound variable "); - } + // Update to the next request + impl->updateToNextRequest(acqRequest.m_vIdentifier); } } else { - qCCritical(LOG_VariableAcquisitionWorker()) - << tr("Impossible to retrieve AcquisitionRequest for the incoming data"); + qCWarning(LOG_VariableAcquisitionWorker()) + << tr("Impossible to retrieve AcquisitionRequest for the incoming data."); } impl->unlock(); } +void VariableAcquisitionWorker::onExecuteRequest(QUuid acqIdentifier) +{ + qCDebug(LOG_VariableAcquisitionWorker()) << tr("onExecuteRequest") << QThread::currentThread(); + impl->lockRead(); + auto it = impl->m_AcqIdentifierToAcqRequestMap.find(acqIdentifier); + if (it != impl->m_AcqIdentifierToAcqRequestMap.cend()) { + auto request = it->second; + impl->unlock(); + emit variableRequestInProgress(request.m_vIdentifier, 0.1); + request.m_Provider->requestDataLoading(acqIdentifier, request.m_DataProviderParameters); + } + else { + impl->unlock(); + // TODO log no acqIdentifier recognized + } +} + void VariableAcquisitionWorker::initialize() { qCDebug(LOG_VariableAcquisitionWorker()) << tr("VariableAcquisitionWorker init") @@ -221,18 +293,30 @@ void VariableAcquisitionWorker::VariableAcquisitionWorkerPrivate::removeVariable unlock(); } -void VariableAcquisitionWorker::onExecuteRequest(QUuid acqIdentifier) +void VariableAcquisitionWorker::VariableAcquisitionWorkerPrivate::updateToNextRequest( + QUuid vIdentifier) { - qCDebug(LOG_VariableAcquisitionWorker()) << tr("onExecuteRequest") << QThread::currentThread(); - impl->lockRead(); - auto it = impl->m_AcqIdentifierToAcqRequestMap.find(acqIdentifier); - if (it != impl->m_AcqIdentifierToAcqRequestMap.cend()) { - auto request = it->second; - impl->unlock(); - request.m_Provider->requestDataLoading(acqIdentifier, request.m_DataProviderParameters); + auto it = m_VIdentifierToCurrrentAcqIdNextIdPairMap.find(vIdentifier); + if (it != m_VIdentifierToCurrrentAcqIdNextIdPairMap.cend()) { + if (it->second.second.isNull()) { + // There is no next request, we can remove the variable request + removeVariableRequest(vIdentifier); + } + else { + auto acqIdentifierToRemove = it->second.first; + // Move the next request to the current request + it->second.first = it->second.second; + it->second.second = QUuid(); + // Remove AcquisitionRequest and results; + m_AcqIdentifierToAcqRequestMap.erase(acqIdentifierToRemove); + m_AcqIdentifierToAcqDataPacketVectorMap.erase(acqIdentifierToRemove); + // Execute the current request + QMetaObject::invokeMethod(q, "onExecuteRequest", Qt::QueuedConnection, + Q_ARG(QUuid, it->second.first)); + } } else { - impl->unlock(); - // TODO log no acqIdentifier recognized + qCCritical(LOG_VariableAcquisitionWorker()) + << tr("Impossible to execute the acquisition on an unfound variable "); } } diff --git a/core/src/Variable/VariableController.cpp b/core/src/Variable/VariableController.cpp index 3aa437b..07674c7 100644 --- a/core/src/Variable/VariableController.cpp +++ b/core/src/Variable/VariableController.cpp @@ -151,12 +151,17 @@ VariableController::VariableController(QObject *parent) connect(impl->m_VariableModel, &VariableModel::abortProgessRequested, this, &VariableController::onAbortProgressRequested); + connect(impl->m_VariableAcquisitionWorker.get(), + &VariableAcquisitionWorker::variableCanceledRequested, this, + &VariableController::onAbortAcquisitionRequested); + connect(impl->m_VariableAcquisitionWorker.get(), &VariableAcquisitionWorker::dataProvided, this, &VariableController::onDataProvided); connect(impl->m_VariableAcquisitionWorker.get(), &VariableAcquisitionWorker::variableRequestInProgress, this, &VariableController::onVariableRetrieveDataInProgress); + connect(&impl->m_VariableAcquisitionWorkerThread, &QThread::started, impl->m_VariableAcquisitionWorker.get(), &VariableAcquisitionWorker::initialize); connect(&impl->m_VariableAcquisitionWorkerThread, &QThread::finished, @@ -253,10 +258,6 @@ void VariableController::deleteVariables( } } -void VariableController::abortProgress(std::shared_ptr variable) -{ -} - std::shared_ptr VariableController::createVariable(const QString &name, const QVariantHash &metadata, std::shared_ptr provider) noexcept @@ -269,7 +270,7 @@ VariableController::createVariable(const QString &name, const QVariantHash &meta auto range = impl->m_TimeController->dateTime(); - if (auto newVariable = impl->m_VariableModel->createVariable(name, range, metadata)) { + if (auto newVariable = impl->m_VariableModel->createVariable(name, metadata)) { auto identifier = QUuid::createUuid(); // store the provider @@ -277,11 +278,11 @@ VariableController::createVariable(const QString &name, const QVariantHash &meta // Associate the provider impl->m_VariableToProviderMap[newVariable] = provider; + qCInfo(LOG_VariableController()) << "createVariable: " << identifier; impl->m_VariableToIdentifierMap[newVariable] = identifier; auto varRequestId = QUuid::createUuid(); - qCInfo(LOG_VariableController()) << "processRequest for" << name << varRequestId; impl->processRequest(newVariable, range, varRequestId); impl->updateVariableRequest(varRequestId); @@ -322,6 +323,9 @@ void VariableController::onDataProvided(QUuid vIdentifier, const SqpRange &range void VariableController::onVariableRetrieveDataInProgress(QUuid identifier, double progress) { + qCDebug(LOG_VariableController()) + << "TORM: variableController::onVariableRetrieveDataInProgress" + << QThread::currentThread()->objectName() << progress; if (auto var = impl->findVariable(identifier)) { impl->m_VariableModel->setDataProgress(var, progress); } @@ -333,12 +337,25 @@ void VariableController::onVariableRetrieveDataInProgress(QUuid identifier, doub void VariableController::onAbortProgressRequested(std::shared_ptr variable) { - qCDebug(LOG_VariableController()) << "TORM: VariableController::onAbortProgressRequested" - << QThread::currentThread()->objectName(); - auto it = impl->m_VariableToIdentifierMap.find(variable); if (it != impl->m_VariableToIdentifierMap.cend()) { - impl->m_VariableToProviderMap.at(variable)->requestDataAborting(it->second); + impl->m_VariableAcquisitionWorker->abortProgressRequested(it->second); + + QUuid varRequestId; + auto varIdToVarRequestIdQueueMapIt = impl->m_VarIdToVarRequestIdQueueMap.find(it->second); + if (varIdToVarRequestIdQueueMapIt != impl->m_VarIdToVarRequestIdQueueMap.cend()) { + auto &varRequestIdQueue = varIdToVarRequestIdQueueMapIt->second; + varRequestId = varRequestIdQueue.front(); + impl->cancelVariableRequest(varRequestId); + + // Finish the progression for the request + impl->m_VariableModel->setDataProgress(variable, 0.0); + } + else { + qCWarning(LOG_VariableController()) + << tr("Aborting progression of inexistant variable request detected !!!") + << QThread::currentThread()->objectName(); + } } else { qCWarning(LOG_VariableController()) @@ -347,6 +364,20 @@ void VariableController::onAbortProgressRequested(std::shared_ptr vari } } +void VariableController::onAbortAcquisitionRequested(QUuid vIdentifier) +{ + qCDebug(LOG_VariableController()) << "TORM: variableController::onAbortAcquisitionRequested" + << QThread::currentThread()->objectName() << vIdentifier; + + if (auto var = impl->findVariable(vIdentifier)) { + this->onAbortProgressRequested(var); + } + else { + qCCritical(LOG_VariableController()) + << tr("Impossible to abort Acquisition Requestof a null variable"); + } +} + void VariableController::onAddSynchronizationGroupId(QUuid synchronizationGroupId) { qCDebug(LOG_VariableController()) << "TORM: VariableController::onAddSynchronizationGroupId" @@ -431,8 +462,8 @@ void VariableController::onRequestDataLoading(QVector // For the other, we ask the provider to give them. auto varRequestId = QUuid::createUuid(); - qCInfo(LOG_VariableController()) << "VariableController::onRequestDataLoading" - << QThread::currentThread()->objectName() << varRequestId; + qCDebug(LOG_VariableController()) << "VariableController::onRequestDataLoading" + << QThread::currentThread()->objectName() << varRequestId; for (const auto &var : variables) { qCDebug(LOG_VariableController()) << "processRequest for" << var->name() << varRequestId; @@ -549,11 +580,7 @@ void VariableController::VariableControllerPrivate::processRequest(std::shared_p if (!notInCacheRangeList.empty()) { varRequest.m_RangeRequested = varStrategyRangesRequested.first; varRequest.m_CacheRangeRequested = varStrategyRangesRequested.second; - qCDebug(LOG_VariableAcquisitionWorker()) << tr("TORM processRequest RR ") << rangeRequested; - qCDebug(LOG_VariableAcquisitionWorker()) << tr("TORM processRequest R ") - << varStrategyRangesRequested.first; - qCDebug(LOG_VariableAcquisitionWorker()) << tr("TORM processRequest CR ") - << varStrategyRangesRequested.second; + // store VarRequest storeVariableRequest(varId, varRequestId, varRequest); @@ -566,8 +593,8 @@ void VariableController::VariableControllerPrivate::processRequest(std::shared_p varProvider); if (!varRequestIdCanceled.isNull()) { - qCInfo(LOG_VariableAcquisitionWorker()) << tr("varRequestIdCanceled: ") - << varRequestIdCanceled; + qCDebug(LOG_VariableAcquisitionWorker()) << tr("vsarRequestIdCanceled: ") + << varRequestIdCanceled; cancelVariableRequest(varRequestIdCanceled); } } @@ -581,7 +608,6 @@ void VariableController::VariableControllerPrivate::processRequest(std::shared_p } } else { - varRequest.m_RangeRequested = varStrategyRangesRequested.first; varRequest.m_CacheRangeRequested = varStrategyRangesRequested.second; // store VarRequest @@ -639,6 +665,9 @@ void VariableController::VariableControllerPrivate::registerProvider( connect(provider.get(), &IDataProvider::dataProvidedProgress, m_VariableAcquisitionWorker.get(), &VariableAcquisitionWorker::onVariableRetrieveDataInProgress); + connect(provider.get(), &IDataProvider::dataProvidedFailed, + m_VariableAcquisitionWorker.get(), + &VariableAcquisitionWorker::onVariableAcquisitionFailed); } else { qCDebug(LOG_VariableController()) << tr("Cannot register provider, it already exists "); @@ -709,12 +738,10 @@ QUuid VariableController::VariableControllerPrivate::acceptVariableRequest( << varRequestId; } - qCDebug(LOG_VariableController()) << tr("1: erase REQUEST in QUEUE ?") - << varRequestIdQueue.size(); varRequestIdQueue.pop_front(); - qCDebug(LOG_VariableController()) << tr("2: erase REQUEST in QUEUE ?") - << varRequestIdQueue.size(); if (varRequestIdQueue.empty()) { + qCDebug(LOG_VariableController()) + << tr("TORM Erase REQUEST because it has been accepted") << varId; m_VarIdToVarRequestIdQueueMap.erase(varId); } } @@ -759,9 +786,11 @@ void VariableController::VariableControllerPrivate::updateVariableRequest(QUuid /// @todo MPL: confirm // Variable update is notified only if there is no pending request for it - if (m_VarIdToVarRequestIdQueueMap.count(varIdToVarRequestMapIt->first) == 0) { - emit var->updated(); - } + // if + // (m_VarIdToVarRequestIdQueueMap.count(varIdToVarRequestMapIt->first) + // == 0) { + emit var->updated(); + // } } else { qCCritical(LOG_VariableController()) diff --git a/core/src/Variable/VariableModel.cpp b/core/src/Variable/VariableModel.cpp index 13e4d70..e5f9947 100644 --- a/core/src/Variable/VariableModel.cpp +++ b/core/src/Variable/VariableModel.cpp @@ -97,10 +97,9 @@ bool VariableModel::containsVariable(std::shared_ptr variable) const n } std::shared_ptr VariableModel::createVariable(const QString &name, - const SqpRange &dateTime, const QVariantHash &metadata) noexcept { - auto variable = std::make_shared(name, dateTime, metadata); + auto variable = std::make_shared(name, metadata); addVariable(variable); return variable; diff --git a/core/tests/Data/TestTwoDimArrayData.cpp b/core/tests/Data/TestTwoDimArrayData.cpp index d644a47..b608a98 100644 --- a/core/tests/Data/TestTwoDimArrayData.cpp +++ b/core/tests/Data/TestTwoDimArrayData.cpp @@ -87,8 +87,8 @@ void TestTwoDimArrayData::testCtor_data() << true << Container{{1., 2., 3., 4., 5.}, {6., 7., 8., 9., 10.}, {11., 12., 13., 14., 15.}}; - QTest::newRow("invalidInput (invalid data size") - << InputData{{1., 2., 3., 4., 5., 6., 7.}, 3} << false << Container{{}, {}, {}}; + QTest::newRow("invalidInput (invalid data size") << InputData{{1., 2., 3., 4., 5., 6., 7.}, 3} + << false << Container{{}, {}, {}}; QTest::newRow("invalidInput (less than two components") << flatten(Container{{1., 2., 3., 4., 5.}}) << false << Container{{}, {}, {}}; } diff --git a/core/tests/Variable/TestVariable.cpp b/core/tests/Variable/TestVariable.cpp index 3fb2623..e6688fa 100644 --- a/core/tests/Variable/TestVariable.cpp +++ b/core/tests/Variable/TestVariable.cpp @@ -24,10 +24,12 @@ void TestVariable::testNotInCacheRangeList() auto varCRS = QDateTime{QDate{2017, 01, 01}, QTime{2, 3, 0, 0}}; auto varCRE = QDateTime{QDate{2017, 01, 01}, QTime{2, 4, 0, 0}}; + auto sqpCR = SqpRange{DateUtils::secondsSinceEpoch(varCRS), DateUtils::secondsSinceEpoch(varCRE)}; - Variable var{"Var test", sqpR}; + Variable var{"Var test"}; + var.setRange(sqpR); var.setCacheRange(sqpCR); // 1: [ts,te] < varTS @@ -109,7 +111,8 @@ void TestVariable::testInCacheRangeList() auto sqpCR = SqpRange{DateUtils::secondsSinceEpoch(varCRS), DateUtils::secondsSinceEpoch(varCRE)}; - Variable var{"Var test", sqpR}; + Variable var{"Var test"}; + var.setRange(sqpR); var.setCacheRange(sqpCR); // 1: [ts,te] < varTS diff --git a/core/tests/Variable/TestVariableCacheController.cpp b/core/tests/Variable/TestVariableCacheController.cpp index 326410b..628da67 100644 --- a/core/tests/Variable/TestVariableCacheController.cpp +++ b/core/tests/Variable/TestVariableCacheController.cpp @@ -32,7 +32,8 @@ void TestVariableCacheController::testProvideNotInCacheDateTimeList() auto te2 = QDateTime{QDate{2017, 01, 01}, QTime{2, 20, 0, 0}}; auto sqp2 = SqpRange{DateUtils::secondsSinceEpoch(ts2), DateUtils::secondsSinceEpoch(te2)}; - auto var0 = std::make_shared("", sqp0); + auto var0 = std::make_shared(""); + var0->setRange(sqp0); variableCacheController.addDateTime(var0, sqp0); variableCacheController.addDateTime(var0, sqp1); @@ -267,7 +268,8 @@ void TestVariableCacheController::testAddDateTime() auto sqp03 = SqpRange{DateUtils::secondsSinceEpoch(ts03), DateUtils::secondsSinceEpoch(te03)}; - auto var0 = std::make_shared("", sqp0); + auto var0 = std::make_shared(""); + var0->setRange(sqp0); // First case: add the first interval to the variable :sqp0 diff --git a/gui/src/Visualization/qcustomplot.cpp b/gui/src/Visualization/qcustomplot.cpp index 5ecb630..5be83c0 100644 --- a/gui/src/Visualization/qcustomplot.cpp +++ b/gui/src/Visualization/qcustomplot.cpp @@ -1574,7 +1574,10 @@ void QCPLayerable::applyAntialiasingHint(QCPPainter *painter, bool localAntialia \see initializeParentPlot */ -void QCPLayerable::parentPlotInitialized(QCustomPlot *parentPlot){Q_UNUSED(parentPlot)} +void QCPLayerable::parentPlotInitialized(QCustomPlot *parentPlot) +{ + Q_UNUSED(parentPlot) +} /*! \internal @@ -9391,16 +9394,14 @@ void QCPAxisPainterPrivate::draw(QCPPainter *painter) painter->setBrush(QBrush(basePen.color())); QCPVector2D baseLineVector(baseLine.dx(), baseLine.dy()); if (lowerEnding.style() != QCPLineEnding::esNone) - lowerEnding.draw(painter, - QCPVector2D(baseLine.p1()) - - baseLineVector.normalized() * lowerEnding.realLength() - * (lowerEnding.inverted() ? -1 : 1), + lowerEnding.draw(painter, QCPVector2D(baseLine.p1()) + - baseLineVector.normalized() * lowerEnding.realLength() + * (lowerEnding.inverted() ? -1 : 1), -baseLineVector); if (upperEnding.style() != QCPLineEnding::esNone) - upperEnding.draw(painter, - QCPVector2D(baseLine.p2()) - + baseLineVector.normalized() * upperEnding.realLength() - * (upperEnding.inverted() ? -1 : 1), + upperEnding.draw(painter, QCPVector2D(baseLine.p2()) + + baseLineVector.normalized() * upperEnding.realLength() + * (upperEnding.inverted() ? -1 : 1), baseLineVector); painter->setAntialiasing(antialiasingBackup); @@ -16629,9 +16630,8 @@ void QCPColorGradient::updateColorBuffer() hue -= 1.0; if (useAlpha) { const QRgb rgb - = QColor::fromHsvF(hue, - (1 - t) * lowHsv.saturationF() - + t * highHsv.saturationF(), + = QColor::fromHsvF(hue, (1 - t) * lowHsv.saturationF() + + t * highHsv.saturationF(), (1 - t) * lowHsv.valueF() + t * highHsv.valueF()) .rgb(); const float alpha = (1 - t) * lowHsv.alphaF() + t * highHsv.alphaF(); @@ -16640,9 +16640,8 @@ void QCPColorGradient::updateColorBuffer() } else { mColorBuffer[i] - = QColor::fromHsvF(hue, - (1 - t) * lowHsv.saturationF() - + t * highHsv.saturationF(), + = QColor::fromHsvF(hue, (1 - t) * lowHsv.saturationF() + + t * highHsv.saturationF(), (1 - t) * lowHsv.valueF() + t * highHsv.valueF()) .rgb(); } @@ -19999,14 +19998,12 @@ void QCPColorScale::update(UpdatePhase phase) switch (phase) { case upMargins: { if (mType == QCPAxis::atBottom || mType == QCPAxis::atTop) { - setMaximumSize(QWIDGETSIZE_MAX, - mBarWidth + mAxisRect.data()->margins().top() - + mAxisRect.data()->margins().bottom() + margins().top() - + margins().bottom()); - setMinimumSize(0, - mBarWidth + mAxisRect.data()->margins().top() - + mAxisRect.data()->margins().bottom() + margins().top() - + margins().bottom()); + setMaximumSize(QWIDGETSIZE_MAX, mBarWidth + mAxisRect.data()->margins().top() + + mAxisRect.data()->margins().bottom() + + margins().top() + margins().bottom()); + setMinimumSize(0, mBarWidth + mAxisRect.data()->margins().top() + + mAxisRect.data()->margins().bottom() + margins().top() + + margins().bottom()); } else { setMaximumSize(mBarWidth + mAxisRect.data()->margins().left() diff --git a/plugins/amda/include/AmdaProvider.h b/plugins/amda/include/AmdaProvider.h index 16a25b9..3736954 100644 --- a/plugins/amda/include/AmdaProvider.h +++ b/plugins/amda/include/AmdaProvider.h @@ -7,15 +7,18 @@ #include +#include Q_DECLARE_LOGGING_CATEGORY(LOG_AmdaProvider) class QNetworkReply; +class QNetworkRequest; /** * @brief The AmdaProvider class is an example of how a data provider can generate data */ class SCIQLOP_AMDA_EXPORT AmdaProvider : public IDataProvider { + Q_OBJECT public: explicit AmdaProvider(); std::shared_ptr clone() const override; @@ -24,8 +27,18 @@ public: void requestDataAborting(QUuid acqIdentifier) override; +private slots: + void onReplyDownloadProgress(QUuid acqIdentifier, + std::shared_ptr networkRequest, double progress); + private: void retrieveData(QUuid token, const SqpRange &dateTime, const QVariantHash &data); + + void updateRequestProgress(QUuid acqIdentifier, std::shared_ptr request, + double progress); + + std::map, double> > + m_AcqIdToRequestProgressMap; }; #endif // SCIQLOP_AMDAPROVIDER_H diff --git a/plugins/amda/src/AmdaProvider.cpp b/plugins/amda/src/AmdaProvider.cpp index d17e6f9..7f7e1cf 100644 --- a/plugins/amda/src/AmdaProvider.cpp +++ b/plugins/amda/src/AmdaProvider.cpp @@ -56,15 +56,17 @@ AmdaProvider::AmdaProvider() qCDebug(LOG_AmdaProvider()) << tr("AmdaProvider::AmdaProvider") << QThread::currentThread(); if (auto app = sqpApp) { auto &networkController = app->networkController(); - connect(this, SIGNAL(requestConstructed(QNetworkRequest, QUuid, + connect(this, SIGNAL(requestConstructed(std::shared_ptr, QUuid, std::function)), &networkController, - SLOT(onProcessRequested(QNetworkRequest, QUuid, + SLOT(onProcessRequested(std::shared_ptr, QUuid, std::function))); - connect(&sqpApp->networkController(), SIGNAL(replyDownloadProgress(QUuid, double)), this, - SIGNAL(dataProvidedProgress(QUuid, double))); + connect(&sqpApp->networkController(), + SIGNAL(replyDownloadProgress(QUuid, std::shared_ptr, double)), + this, + SLOT(onReplyDownloadProgress(QUuid, std::shared_ptr, double))); } } @@ -80,8 +82,11 @@ void AmdaProvider::requestDataLoading(QUuid acqIdentifier, const DataProviderPar const auto times = parameters.m_Times; const auto data = parameters.m_Data; for (const auto &dateTime : qAsConst(times)) { + qCDebug(LOG_AmdaProvider()) << tr("TORM AmdaProvider::requestDataLoading ") << acqIdentifier + << dateTime; this->retrieveData(acqIdentifier, dateTime, data); + // TORM when AMDA will support quick asynchrone request QThread::msleep(1000); } @@ -95,6 +100,60 @@ void AmdaProvider::requestDataAborting(QUuid acqIdentifier) } } +void AmdaProvider::onReplyDownloadProgress(QUuid acqIdentifier, + std::shared_ptr networkRequest, + double progress) +{ + qCDebug(LOG_AmdaProvider()) << tr("onReplyDownloadProgress") << acqIdentifier + << networkRequest.get() << progress; + auto acqIdToRequestProgressMapIt = m_AcqIdToRequestProgressMap.find(acqIdentifier); + if (acqIdToRequestProgressMapIt != m_AcqIdToRequestProgressMap.end()) { + + // Update the progression for the current request + auto requestPtr = networkRequest; + auto findRequest = [requestPtr](const auto &entry) { return requestPtr == entry.first; }; + + auto &requestProgressMap = acqIdToRequestProgressMapIt->second; + auto requestProgressMapEnd = requestProgressMap.end(); + auto requestProgressMapIt + = std::find_if(requestProgressMap.begin(), requestProgressMapEnd, findRequest); + + if (requestProgressMapIt != requestProgressMapEnd) { + requestProgressMapIt->second = progress; + } + else { + // This case can happened when a progression is send after the request has been + // finished. + // Generaly the case when aborting a request + qCDebug(LOG_AmdaProvider()) << tr("Can't retrieve Request in progress") << acqIdentifier + << networkRequest.get() << progress; + } + + // Compute the current final progress and notify it + double finalProgress = 0.0; + + auto fraq = requestProgressMap.size(); + + for (auto requestProgress : requestProgressMap) { + finalProgress += requestProgress.second; + qCDebug(LOG_AmdaProvider()) << tr("Current final progress without fraq:") + << finalProgress << requestProgress.second; + } + + if (fraq > 0) { + finalProgress = finalProgress / fraq; + } + + qCDebug(LOG_AmdaProvider()) << tr("Current final progress: ") << fraq << finalProgress; + emit dataProvidedProgress(acqIdentifier, finalProgress); + } + else { + // This case can happened when a progression is send after the request has been finished. + // Generaly the case when aborting a request + emit dataProvidedProgress(acqIdentifier, 100.0); + } +} + void AmdaProvider::retrieveData(QUuid token, const SqpRange &dateTime, const QVariantHash &data) { // Retrieves product ID from data: if the value is invalid, no request is made @@ -103,7 +162,6 @@ void AmdaProvider::retrieveData(QUuid token, const SqpRange &dateTime, const QVa qCCritical(LOG_AmdaProvider()) << tr("Can't retrieve data: unknown product id"); return; } - qCDebug(LOG_AmdaProvider()) << tr("AmdaProvider::retrieveData") << dateTime; // Retrieves the data type that determines whether the expected format for the result file is // scalar, vector... @@ -125,7 +183,7 @@ void AmdaProvider::retrieveData(QUuid token, const SqpRange &dateTime, const QVa productValueType](QNetworkReply *reply, QUuid dataId) noexcept { // Don't do anything if the reply was abort - if (reply->error() != QNetworkReply::OperationCanceledError) { + if (reply->error() == QNetworkReply::NoError) { if (tempFile) { auto replyReadAll = reply->readAll(); @@ -141,8 +199,16 @@ void AmdaProvider::retrieveData(QUuid token, const SqpRange &dateTime, const QVa } else { /// @todo ALX : debug + emit dataProvidedFailed(dataId); } } + qCDebug(LOG_AmdaProvider()) << tr("acquisition requests erase because of finishing") + << dataId; + m_AcqIdToRequestProgressMap.erase(dataId); + } + else { + qCCritical(LOG_AmdaProvider()) << tr("httpDownloadFinished ERROR"); + emit dataProvidedFailed(dataId); } }; @@ -150,25 +216,68 @@ void AmdaProvider::retrieveData(QUuid token, const SqpRange &dateTime, const QVa = [this, httpDownloadFinished, tempFile](QNetworkReply *reply, QUuid dataId) noexcept { // Don't do anything if the reply was abort - if (reply->error() != QNetworkReply::OperationCanceledError) { + if (reply->error() == QNetworkReply::NoError) { auto downloadFileUrl = QUrl{QString{reply->readAll()}}; - qCInfo(LOG_AmdaProvider()) << tr("TORM AmdaProvider::retrieveData downloadFileUrl:") << downloadFileUrl; // Executes request for downloading file // // Creates destination file if (tempFile->open()) { - // Executes request - emit requestConstructed(QNetworkRequest{downloadFileUrl}, dataId, - httpDownloadFinished); + // Executes request and store the request for progression + auto request = std::make_shared(downloadFileUrl); + updateRequestProgress(dataId, request, 0.0); + emit requestConstructed(request, dataId, httpDownloadFinished); } + else { + emit dataProvidedFailed(dataId); + } + } + else { + qCDebug(LOG_AmdaProvider()) + << tr("acquisition requests erase because of aborting") << dataId; + qCCritical(LOG_AmdaProvider()) << tr("httpFinishedLambda ERROR"); + m_AcqIdToRequestProgressMap.erase(dataId); + emit dataProvidedFailed(dataId); } }; // //////////////// // // Executes request // // //////////////// // - emit requestConstructed(QNetworkRequest{url}, token, httpFinishedLambda); + + auto request = std::make_shared(url); + qCDebug(LOG_AmdaProvider()) << tr("First Request creation") << request.get(); + updateRequestProgress(token, request, 0.0); + + emit requestConstructed(request, token, httpFinishedLambda); +} + +void AmdaProvider::updateRequestProgress(QUuid acqIdentifier, + std::shared_ptr request, double progress) +{ + auto acqIdToRequestProgressMapIt = m_AcqIdToRequestProgressMap.find(acqIdentifier); + if (acqIdToRequestProgressMapIt != m_AcqIdToRequestProgressMap.end()) { + auto &requestProgressMap = acqIdToRequestProgressMapIt->second; + auto requestProgressMapIt = requestProgressMap.find(request); + if (requestProgressMapIt != requestProgressMap.end()) { + requestProgressMapIt->second = progress; + qCDebug(LOG_AmdaProvider()) << tr("updateRequestProgress new progress for request") + << acqIdentifier << request.get() << progress; + } + else { + qCDebug(LOG_AmdaProvider()) << tr("updateRequestProgress new request") << acqIdentifier + << request.get() << progress; + acqIdToRequestProgressMapIt->second.insert(std::make_pair(request, progress)); + } + } + else { + qCDebug(LOG_AmdaProvider()) << tr("updateRequestProgress new acqIdentifier") + << acqIdentifier << request.get() << progress; + auto requestProgressMap = std::map, double>{}; + requestProgressMap.insert(std::make_pair(request, progress)); + m_AcqIdToRequestProgressMap.insert( + std::make_pair(acqIdentifier, std::move(requestProgressMap))); + } } diff --git a/plugins/amda/tests/TestAmdaAcquisition.cpp b/plugins/amda/tests/TestAmdaAcquisition.cpp index 60662bb..92d0b35 100644 --- a/plugins/amda/tests/TestAmdaAcquisition.cpp +++ b/plugins/amda/tests/TestAmdaAcquisition.cpp @@ -100,8 +100,6 @@ void TestAmdaAcquisition::testAcquisition() auto var = vc.createVariable("bx_gse", metaData, provider); // 1 : Variable creation - QCOMPARE(var->range().m_TStart, sqpR.m_TStart); - QCOMPARE(var->range().m_TEnd, sqpR.m_TEnd); qDebug() << " 1: TIMECONTROLLER" << timeController->dateTime(); qDebug() << " 1: RANGE " << var->range(); diff --git a/plugins/mockplugin/src/CosinusProvider.cpp b/plugins/mockplugin/src/CosinusProvider.cpp index 815e550..bab6302 100644 --- a/plugins/mockplugin/src/CosinusProvider.cpp +++ b/plugins/mockplugin/src/CosinusProvider.cpp @@ -59,6 +59,9 @@ std::shared_ptr CosinusProvider::retrieveData(QUuid acqIdentifier, progress = currentProgress; emit dataProvidedProgress(acqIdentifier, progress); + qCInfo(LOG_CosinusProvider()) << "TORM: CosinusProvider::retrieveData" + << QThread::currentThread()->objectName() << progress; + // NOTE: Try to use multithread if possible } } else { @@ -69,8 +72,10 @@ std::shared_ptr CosinusProvider::retrieveData(QUuid acqIdentifier, } } } - emit dataProvidedProgress(acqIdentifier, 0.0); - + if (progress != 100) { + // We can close progression beacause all data has been retrieved + emit dataProvidedProgress(acqIdentifier, 100); + } return std::make_shared(std::move(xAxisData), std::move(valuesData), Unit{QStringLiteral("t"), true}, Unit{}); }