##// END OF EJS Templates
commit
Alexandre Leroux -
r681:5e6b86368b57
parent child
Show More
@@ -1,80 +1,88
1 /*------------------------------------------------------------------------------
1 /*------------------------------------------------------------------------------
2 -- This file is a part of the QLop Software
2 -- This file is a part of the QLop Software
3 -- Copyright (C) 2015, Plasma Physics Laboratory - CNRS
3 -- Copyright (C) 2015, Plasma Physics Laboratory - CNRS
4 --
4 --
5 -- This program is free software; you can redistribute it and/or modify
5 -- This program is free software; you can redistribute it and/or modify
6 -- it under the terms of the GNU General Public License as published by
6 -- it under the terms of the GNU General Public License as published by
7 -- the Free Software Foundation; either version 2 of the License, or
7 -- the Free Software Foundation; either version 2 of the License, or
8 -- (at your option) any later version.
8 -- (at your option) any later version.
9 --
9 --
10 -- This program is distributed in the hope that it will be useful,
10 -- This program is distributed in the hope that it will be useful,
11 -- but WITHOUT ANY WARRANTY; without even the implied warranty of
11 -- but WITHOUT ANY WARRANTY; without even the implied warranty of
12 -- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 -- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 -- GNU General Public License for more details.
13 -- GNU General Public License for more details.
14 --
14 --
15 -- You should have received a copy of the GNU General Public License
15 -- You should have received a copy of the GNU General Public License
16 -- along with this program; if not, write to the Free Software
16 -- along with this program; if not, write to the Free Software
17 -- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 -- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18 -------------------------------------------------------------------------------*/
18 -------------------------------------------------------------------------------*/
19 /*-- Author : Alexis Jeandet
19 /*-- Author : Alexis Jeandet
20 -- Mail : alexis.jeandet@member.fsf.org
20 -- Mail : alexis.jeandet@member.fsf.org
21 ----------------------------------------------------------------------------*/
21 ----------------------------------------------------------------------------*/
22 #include "MainWindow.h"
22 #include "MainWindow.h"
23 #include <QProcessEnvironment>
23 #include <QProcessEnvironment>
24 #include <QThread>
24 #include <QThread>
25 #include <SqpApplication.h>
25 #include <SqpApplication.h>
26 #include <qglobal.h>
26 #include <qglobal.h>
27
27
28 #include <Plugin/PluginManager.h>
28 #include <Plugin/PluginManager.h>
29 #include <QDir>
29 #include <QDir>
30
30
31 #include <QLoggingCategory>
31 #include <QLoggingCategory>
32
32
33 Q_LOGGING_CATEGORY(LOG_Main, "Main")
33 Q_LOGGING_CATEGORY(LOG_Main, "Main")
34
34
35 namespace {
35 namespace {
36
36
37 const auto PLUGIN_DIRECTORY_NAME = QStringLiteral("plugins");
37 const auto PLUGIN_DIRECTORY_NAME = QStringLiteral("plugins");
38
38
39
39
40 } // namespace
40 } // namespace
41
41
42 int main(int argc, char *argv[])
42 int main(int argc, char *argv[])
43 {
43 {
44 QLoggingCategory::setFilterRules(
45 "*.warning=false\n"
46 "*.info=false\n"
47 "*.debug=false\n"
48 "AmdaProvider.info=true\n"
49 "NetworkController.info=true\n"
50 "VariableAcquisitionWorker.info=true\n");
51
44 SqpApplication a{argc, argv};
52 SqpApplication a{argc, argv};
45 SqpApplication::setOrganizationName("LPP");
53 SqpApplication::setOrganizationName("LPP");
46 SqpApplication::setOrganizationDomain("lpp.fr");
54 SqpApplication::setOrganizationDomain("lpp.fr");
47 SqpApplication::setApplicationName("SciQLop");
55 SqpApplication::setApplicationName("SciQLop");
48 MainWindow w;
56 MainWindow w;
49 w.show();
57 w.show();
50
58
51 // Loads plugins
59 // Loads plugins
52 auto pluginDir = QDir{a.applicationDirPath()};
60 auto pluginDir = QDir{a.applicationDirPath()};
53 auto pluginLookupPath = {
61 auto pluginLookupPath = {
54 a.applicationDirPath(),
62 a.applicationDirPath(),
55 a.applicationDirPath() + "/" + PLUGIN_DIRECTORY_NAME,
63 a.applicationDirPath() + "/" + PLUGIN_DIRECTORY_NAME,
56 a.applicationDirPath() + "/../lib64/SciQlop",
64 a.applicationDirPath() + "/../lib64/SciQlop",
57 a.applicationDirPath() + "/../lib64/sciqlop",
65 a.applicationDirPath() + "/../lib64/sciqlop",
58 a.applicationDirPath() + "/../lib/SciQlop",
66 a.applicationDirPath() + "/../lib/SciQlop",
59 a.applicationDirPath() + "/../lib/sciqlop",
67 a.applicationDirPath() + "/../lib/sciqlop",
60 a.applicationDirPath() + "/../plugins",
68 a.applicationDirPath() + "/../plugins",
61 };
69 };
62
70
63 #if _WIN32 || _WIN64
71 #if _WIN32 || _WIN64
64 pluginDir.mkdir(PLUGIN_DIRECTORY_NAME);
72 pluginDir.mkdir(PLUGIN_DIRECTORY_NAME);
65 pluginDir.cd(PLUGIN_DIRECTORY_NAME);
73 pluginDir.cd(PLUGIN_DIRECTORY_NAME);
66 #endif
74 #endif
67
75
68 PluginManager pluginManager{};
76 PluginManager pluginManager{};
69
77
70 for (auto &&path : pluginLookupPath) {
78 for (auto &&path : pluginLookupPath) {
71 QDir directory{path};
79 QDir directory{path};
72 if (directory.exists()) {
80 if (directory.exists()) {
73 qCDebug(LOG_Main())
81 qCDebug(LOG_Main())
74 << QObject::tr("Plugin directory: %1").arg(directory.absolutePath());
82 << QObject::tr("Plugin directory: %1").arg(directory.absolutePath());
75 pluginManager.loadPlugins(directory);
83 pluginManager.loadPlugins(directory);
76 }
84 }
77 }
85 }
78
86
79 return a.exec();
87 return a.exec();
80 }
88 }
@@ -1,38 +1,40
1 #ifndef SCIQLOP_ACQUISITIONREQUEST_H
1 #ifndef SCIQLOP_ACQUISITIONREQUEST_H
2 #define SCIQLOP_ACQUISITIONREQUEST_H
2 #define SCIQLOP_ACQUISITIONREQUEST_H
3
3
4 #include <QObject>
4 #include <QObject>
5
5
6 #include <QUuid>
6 #include <QUuid>
7
7
8 #include <Common/DateUtils.h>
8 #include <Common/DateUtils.h>
9 #include <Common/MetaTypes.h>
9 #include <Common/MetaTypes.h>
10 #include <Data/AcquisitionDataPacket.h>
10 #include <Data/DataProviderParameters.h>
11 #include <Data/DataProviderParameters.h>
11 #include <Data/IDataProvider.h>
12 #include <Data/IDataProvider.h>
12 #include <Data/SqpRange.h>
13 #include <Data/SqpRange.h>
13
14
14 #include <memory>
15 #include <memory>
15
16
16 /**
17 /**
17 * @brief The AcquisitionRequest struct holds the information of an variable request
18 * @brief The AcquisitionRequest struct holds the information of an variable request
18 */
19 */
19 struct AcquisitionRequest {
20 struct AcquisitionRequest {
20 AcquisitionRequest()
21 AcquisitionRequest()
21 {
22 {
22 m_AcqIdentifier = QUuid::createUuid();
23 m_AcqIdentifier = QUuid::createUuid();
23 m_Size = 0;
24 m_Size = 0;
24 }
25 }
25
26
26 QUuid m_VarRequestId;
27 QUuid m_VarRequestId;
27 QUuid m_AcqIdentifier;
28 QUuid m_AcqIdentifier;
28 QUuid m_vIdentifier;
29 QUuid m_vIdentifier;
29 DataProviderParameters m_DataProviderParameters;
30 DataProviderParameters m_DataProviderParameters;
30 SqpRange m_RangeRequested;
31 SqpRange m_RangeRequested;
31 SqpRange m_CacheRangeRequested;
32 SqpRange m_CacheRangeRequested;
32 int m_Size;
33 int m_Size;
33 std::shared_ptr<IDataProvider> m_Provider;
34 std::shared_ptr<IDataProvider> m_Provider;
35 QVector<AcquisitionDataPacket> m_DataPackets;
34 };
36 };
35
37
36 SCIQLOP_REGISTER_META_TYPE(ACQUISITIONREQUEST_REGISTRY, AcquisitionRequest)
38 SCIQLOP_REGISTER_META_TYPE(ACQUISITIONREQUEST_REGISTRY, AcquisitionRequest)
37
39
38 #endif // SCIQLOP_ACQUISITIONREQUEST_H
40 #endif // SCIQLOP_ACQUISITIONREQUEST_H
@@ -1,77 +1,78
1 #ifndef SCIQLOP_IDATAPROVIDER_H
1 #ifndef SCIQLOP_IDATAPROVIDER_H
2 #define SCIQLOP_IDATAPROVIDER_H
2 #define SCIQLOP_IDATAPROVIDER_H
3
3
4 #include "CoreGlobal.h"
4 #include "CoreGlobal.h"
5
5
6 #include <memory>
6 #include <memory>
7
7
8 #include <QObject>
8 #include <QObject>
9 #include <QUuid>
9 #include <QUuid>
10
10
11 #include <Common/MetaTypes.h>
11 #include <Common/MetaTypes.h>
12
12
13 #include <Data/SqpRange.h>
13 #include <Data/SqpRange.h>
14
14
15 #include <functional>
15 #include <functional>
16
16
17 class DataProviderParameters;
17 class DataProviderParameters;
18 class IDataSeries;
18 class IDataSeries;
19 class QNetworkReply;
19 class QNetworkReply;
20 class QNetworkRequest;
20 class QNetworkRequest;
21
21
22 /**
22 /**
23 * @brief The IDataProvider interface aims to declare a data provider.
23 * @brief The IDataProvider interface aims to declare a data provider.
24 *
24 *
25 * A data provider is an entity that generates data and returns it according to various parameters
25 * A data provider is an entity that generates data and returns it according to various parameters
26 * (time interval, product to retrieve the data, etc.)
26 * (time interval, product to retrieve the data, etc.)
27 *
27 *
28 * @sa IDataSeries
28 * @sa IDataSeries
29 */
29 */
30 class SCIQLOP_CORE_EXPORT IDataProvider : public QObject {
30 class SCIQLOP_CORE_EXPORT IDataProvider : public QObject {
31
31
32 Q_OBJECT
32 Q_OBJECT
33 public:
33 public:
34 virtual ~IDataProvider() noexcept = default;
34 virtual ~IDataProvider() noexcept = default;
35 virtual std::shared_ptr<IDataProvider> clone() const = 0;
35 virtual std::shared_ptr<IDataProvider> clone() const = 0;
36
36
37 /**
37 /**
38 * @brief requestDataLoading provide datas for the data identified by acqIdentifier and
38 * @brief requestDataLoading provide datas for the data identified by acqIdentifier and
39 * parameters
39 * parameters
40 */
40 */
41 virtual void requestDataLoading(QUuid acqIdentifier, const DataProviderParameters &parameters)
41 virtual void requestDataLoading(QUuid acqIdentifier, const DataProviderParameters &parameters)
42 = 0;
42 = 0;
43
43
44 /**
44 /**
45 * @brief requestDataAborting stop data loading of the data identified by acqIdentifier
45 * @brief requestDataAborting stop data loading of the data identified by acqIdentifier
46 */
46 */
47 virtual void requestDataAborting(QUuid acqIdentifier) = 0;
47 virtual void requestDataAborting(QUuid acqIdentifier) = 0;
48
48
49 signals:
49 signals:
50 /**
50 /**
51 * @brief dataProvided send dataSeries under dateTime and that corresponds of the data
51 * @brief dataProvided send dataSeries under dateTime and that corresponds of the data
52 * identified by acqIdentifier
52 * identified by acqIdentifier
53 */
53 */
54 void dataProvided(QUuid acqIdentifier, std::shared_ptr<IDataSeries> dateSeriesAcquired,
54 void dataProvided(QUuid acqIdentifier, std::shared_ptr<IDataSeries> dateSeriesAcquired,
55 const SqpRange &dataRangeAcquired);
55 const SqpRange &dataRangeAcquired);
56
56
57 /**
57 /**
58 * @brief dataProvided send dataSeries under dateTime and that corresponds of the data
58 * @brief dataProvided send dataSeries under dateTime and that corresponds of the data
59 * identified by identifier
59 * identified by identifier
60 */
60 */
61 void dataProvidedProgress(QUuid acqIdentifier, double progress);
61 void dataProvidedProgress(QUuid acqIdentifier, double progress);
62
62
63 void requestCanceled(QUuid acqIdentifier);
63
64
64 /**
65 /**
65 * @brief requestConstructed send a request for the data identified by acqIdentifier
66 * @brief requestConstructed send a request for the data identified by acqIdentifier
66 * @callback is the methode call by the reply of the request when it is finished.
67 * @callback is the methode call by the reply of the request when it is finished.
67 */
68 */
68 void requestConstructed(const QNetworkRequest &request, QUuid acqIdentifier,
69 void requestConstructed(const QNetworkRequest &request, QUuid acqIdentifier,
69 std::function<void(QNetworkReply *, QUuid)> callback);
70 std::function<void(QNetworkReply *, QUuid)> callback);
70 };
71 };
71
72
72 // Required for using shared_ptr in signals/slots
73 // Required for using shared_ptr in signals/slots
73 SCIQLOP_REGISTER_META_TYPE(IDATAPROVIDER_PTR_REGISTRY, std::shared_ptr<IDataProvider>)
74 SCIQLOP_REGISTER_META_TYPE(IDATAPROVIDER_PTR_REGISTRY, std::shared_ptr<IDataProvider>)
74 SCIQLOP_REGISTER_META_TYPE(IDATAPROVIDER_FUNCTION_REGISTRY,
75 SCIQLOP_REGISTER_META_TYPE(IDATAPROVIDER_FUNCTION_REGISTRY,
75 std::function<void(QNetworkReply *, QUuid)>)
76 std::function<void(QNetworkReply *, QUuid)>)
76
77
77 #endif // SCIQLOP_IDATAPROVIDER_H
78 #endif // SCIQLOP_IDATAPROVIDER_H
@@ -1,61 +1,62
1 #ifndef SCIQLOP_VARIABLEACQUISITIONWORKER_H
1 #ifndef SCIQLOP_VARIABLEACQUISITIONWORKER_H
2 #define SCIQLOP_VARIABLEACQUISITIONWORKER_H
2 #define SCIQLOP_VARIABLEACQUISITIONWORKER_H
3
3
4 #include "CoreGlobal.h"
4 #include "CoreGlobal.h"
5
5
6 #include <Data/DataProviderParameters.h>
6 #include <Data/DataProviderParameters.h>
7 #include <QLoggingCategory>
7 #include <QLoggingCategory>
8 #include <QObject>
8 #include <QObject>
9 #include <QUuid>
9 #include <QUuid>
10
10
11 #include <Data/AcquisitionDataPacket.h>
11 #include <Data/AcquisitionDataPacket.h>
12 #include <Data/IDataSeries.h>
12 #include <Data/IDataSeries.h>
13 #include <Data/SqpRange.h>
13 #include <Data/SqpRange.h>
14
14
15 #include <QLoggingCategory>
15 #include <QLoggingCategory>
16
16
17 #include <Common/spimpl.h>
17 #include <Common/spimpl.h>
18
18
19 Q_DECLARE_LOGGING_CATEGORY(LOG_VariableAcquisitionWorker)
19 Q_DECLARE_LOGGING_CATEGORY(LOG_VariableAcquisitionWorker)
20
20
21 class Variable;
21 class Variable;
22 class IDataProvider;
22 class IDataProvider;
23
23
24 /// This class aims to handle all acquisition request
24 /// This class aims to handle all acquisition request
25 class SCIQLOP_CORE_EXPORT VariableAcquisitionWorker : public QObject {
25 class SCIQLOP_CORE_EXPORT VariableAcquisitionWorker : public QObject {
26 Q_OBJECT
26 Q_OBJECT
27 public:
27 public:
28 explicit VariableAcquisitionWorker(QObject *parent = 0);
28 explicit VariableAcquisitionWorker(QObject *parent = 0);
29 virtual ~VariableAcquisitionWorker();
29 virtual ~VariableAcquisitionWorker();
30
30
31 QUuid pushVariableRequest(QUuid varRequestId, QUuid vIdentifier, SqpRange rangeRequested,
31 QUuid pushVariableRequest(QUuid varRequestId, QUuid vIdentifier, SqpRange rangeRequested,
32 SqpRange cacheRangeRequested, DataProviderParameters parameters,
32 SqpRange cacheRangeRequested, DataProviderParameters parameters,
33 std::shared_ptr<IDataProvider> provider);
33 std::shared_ptr<IDataProvider> provider);
34
34
35 void abortProgressRequested(QUuid vIdentifier);
35 void abortProgressRequested(QUuid vIdentifier);
36
36
37 void initialize();
37 void initialize();
38 void finalize();
38 void finalize();
39 signals:
39 signals:
40 void dataProvided(QUuid vIdentifier, const SqpRange &rangeRequested,
40 void dataProvided(QUuid vIdentifier, const SqpRange &rangeRequested,
41 const SqpRange &cacheRangeRequested,
41 const SqpRange &cacheRangeRequested,
42 QVector<AcquisitionDataPacket> dataAcquired);
42 QVector<AcquisitionDataPacket> dataAcquired);
43
43
44 void variableRequestInProgress(QUuid vIdentifier, double progress);
44 void variableRequestInProgress(QUuid vIdentifier, double progress);
45
45
46 public slots:
46 public slots:
47 void onVariableDataAcquired(QUuid acqIdentifier, std::shared_ptr<IDataSeries> dataSeries,
47 void onVariableDataAcquired(QUuid acqIdentifier, std::shared_ptr<IDataSeries> dataSeries,
48 SqpRange dataRangeAcquired);
48 SqpRange dataRangeAcquired);
49 void onVariableAcquisitionCanceled(QUuid acqIdentifier);
49 void onVariableRetrieveDataInProgress(QUuid acqIdentifier, double progress);
50 void onVariableRetrieveDataInProgress(QUuid acqIdentifier, double progress);
50
51
51 private:
52 private:
52 void waitForFinish();
53 void waitForFinish();
53
54
54 class VariableAcquisitionWorkerPrivate;
55 class VariableAcquisitionWorkerPrivate;
55 spimpl::unique_impl_ptr<VariableAcquisitionWorkerPrivate> impl;
56 spimpl::unique_impl_ptr<VariableAcquisitionWorkerPrivate> impl;
56
57
57 private slots:
58 private slots:
58 void onExecuteRequest(QUuid acqIdentifier);
59 void onExecuteRequest(QUuid acqIdentifier);
59 };
60 };
60
61
61 #endif // SCIQLOP_VARIABLEACQUISITIONWORKER_H
62 #endif // SCIQLOP_VARIABLEACQUISITIONWORKER_H
@@ -1,134 +1,143
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_NetworkReplyToVariableId;
24 std::unordered_map<QNetworkReply *, QUuid> m_NetworkReplyToVariableId;
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(const QNetworkRequest &request, QUuid identifier,
33 void NetworkController::onProcessRequested(const QNetworkRequest &request, QUuid identifier,
34 std::function<void(QNetworkReply *, QUuid)> callback)
34 std::function<void(QNetworkReply *, QUuid)> callback)
35 {
35 {
36 qCDebug(LOG_NetworkController())
37 << tr("NetworkController registered") << QThread::currentThread()->objectName();
38 auto reply = impl->m_AccessManager->get(request);
39
40 // Store the couple reply id
36 // Store the couple reply id
41 impl->lockWrite();
37 impl->lockWrite();
38 qCInfo(LOG_NetworkController()) << tr("NetworkController registered") << identifier;
39 auto reply = impl->m_AccessManager->get(request);
40
42 impl->m_NetworkReplyToVariableId[reply] = identifier;
41 impl->m_NetworkReplyToVariableId[reply] = identifier;
42 qCInfo(LOG_NetworkController()) << tr("Reply stored") << identifier;
43 impl->unlock();
43 impl->unlock();
44
44
45 auto onReplyFinished = [reply, this, identifier, callback]() {
45 auto onReplyFinished = [reply, this, identifier, callback]() {
46
46
47 qCDebug(LOG_NetworkController())
47 qCInfo(LOG_NetworkController()) << tr("NetworkController onReplyFinished") << identifier;
48 << tr("NetworkController onReplyFinished") << QThread::currentThread() << reply;
49 impl->lockRead();
48 impl->lockRead();
50 auto it = impl->m_NetworkReplyToVariableId.find(reply);
49 auto it = impl->m_NetworkReplyToVariableId.find(reply);
51 impl->unlock();
50 impl->unlock();
52 if (it != impl->m_NetworkReplyToVariableId.cend()) {
51 if (it != impl->m_NetworkReplyToVariableId.cend()) {
53 impl->lockWrite();
52 impl->lockWrite();
54 impl->m_NetworkReplyToVariableId.erase(reply);
53 impl->m_NetworkReplyToVariableId.erase(reply);
55 impl->unlock();
54 impl->unlock();
56 // Deletes reply
55 // Deletes reply
57 callback(reply, identifier);
56 callback(reply, identifier);
58 reply->deleteLater();
57 reply->deleteLater();
59
58
60 emit this->replyDownloadProgress(identifier, 0);
59 emit this->replyDownloadProgress(identifier, 0);
61 }
60 }
62
61
63 qCDebug(LOG_NetworkController())
62 qCDebug(LOG_NetworkController())
64 << tr("NetworkController onReplyFinished END") << QThread::currentThread() << reply;
63 << tr("NetworkController onReplyFinished END") << QThread::currentThread() << reply;
65 };
64 };
66
65
67 auto onReplyProgress = [reply, this](qint64 bytesRead, qint64 totalBytes) {
66 auto onReplyProgress = [reply, this](qint64 bytesRead, qint64 totalBytes) {
68
67
69 double progress = (bytesRead * 100.0) / totalBytes;
68 double progress = (bytesRead * 100.0) / totalBytes;
70 qCDebug(LOG_NetworkController()) << tr("NetworkController onReplyProgress") << progress
69 qCDebug(LOG_NetworkController()) << tr("NetworkController onReplyProgress") << progress
71 << QThread::currentThread() << reply;
70 << QThread::currentThread() << reply;
72 impl->lockRead();
71 impl->lockRead();
73 auto it = impl->m_NetworkReplyToVariableId.find(reply);
72 auto it = impl->m_NetworkReplyToVariableId.find(reply);
74 impl->unlock();
73 impl->unlock();
75 if (it != impl->m_NetworkReplyToVariableId.cend()) {
74 if (it != impl->m_NetworkReplyToVariableId.cend()) {
76 emit this->replyDownloadProgress(it->second, progress);
75 emit this->replyDownloadProgress(it->second, progress);
77 }
76 }
78 qCDebug(LOG_NetworkController())
77 qCDebug(LOG_NetworkController())
79 << tr("NetworkController onReplyProgress END") << QThread::currentThread() << reply;
78 << tr("NetworkController onReplyProgress END") << QThread::currentThread() << reply;
80 };
79 };
81
80
82
81
83 connect(reply, &QNetworkReply::finished, this, onReplyFinished);
82 connect(reply, &QNetworkReply::finished, this, onReplyFinished);
84 connect(reply, &QNetworkReply::downloadProgress, this, onReplyProgress);
83 connect(reply, &QNetworkReply::downloadProgress, this, onReplyProgress);
85 qCDebug(LOG_NetworkController()) << tr("NetworkController registered END")
84 qCDebug(LOG_NetworkController()) << tr("NetworkController registered END")
86 << QThread::currentThread()->objectName() << reply;
85 << QThread::currentThread()->objectName() << reply;
87 }
86 }
88
87
89 void NetworkController::initialize()
88 void NetworkController::initialize()
90 {
89 {
91 qCDebug(LOG_NetworkController()) << tr("NetworkController init") << QThread::currentThread();
90 qCDebug(LOG_NetworkController()) << tr("NetworkController init") << QThread::currentThread();
92 impl->m_WorkingMutex.lock();
91 impl->m_WorkingMutex.lock();
93 impl->m_AccessManager = std::make_unique<QNetworkAccessManager>();
92 impl->m_AccessManager = std::make_unique<QNetworkAccessManager>();
94
93
95
94
96 auto onReplyErrors = [this](QNetworkReply *reply, const QList<QSslError> &errors) {
95 auto onReplyErrors = [this](QNetworkReply *reply, const QList<QSslError> &errors) {
97
96
98 qCCritical(LOG_NetworkController()) << tr("NetworkAcessManager errors: ") << errors;
97 qCCritical(LOG_NetworkController()) << tr("NetworkAcessManager errors: ") << errors;
99
98
100 };
99 };
101
100
102
101
103 connect(impl->m_AccessManager.get(), &QNetworkAccessManager::sslErrors, this, onReplyErrors);
102 connect(impl->m_AccessManager.get(), &QNetworkAccessManager::sslErrors, this, onReplyErrors);
104
103
105 qCDebug(LOG_NetworkController()) << tr("NetworkController init END");
104 qCDebug(LOG_NetworkController()) << tr("NetworkController init END");
106 }
105 }
107
106
108 void NetworkController::finalize()
107 void NetworkController::finalize()
109 {
108 {
110 impl->m_WorkingMutex.unlock();
109 impl->m_WorkingMutex.unlock();
111 }
110 }
112
111
113 void NetworkController::onReplyCanceled(QUuid identifier)
112 void NetworkController::onReplyCanceled(QUuid identifier)
114 {
113 {
115 auto findReply = [identifier](const auto &entry) { return identifier == entry.second; };
114 // auto findReply = [identifier](const auto &entry) { return identifier == entry.second; };
116 qCDebug(LOG_NetworkController())
115 qCDebug(LOG_NetworkController())
117 << tr("NetworkController onReplyCanceled") << QThread::currentThread();
116 << tr("NetworkController onReplyCanceled") << QThread::currentThread();
118
117
118 qCInfo(LOG_NetworkController()) << tr("Calls cancel on ") << identifier;
119
119
120 impl->lockRead();
120 impl->lockWrite();
121 auto end = impl->m_NetworkReplyToVariableId.cend();
121 for (auto &reply : impl->m_NetworkReplyToVariableId) {
122 auto it = std::find_if(impl->m_NetworkReplyToVariableId.cbegin(), end, findReply);
122 if (reply.second == identifier) {
123 impl->unlock();
123 qCInfo(LOG_NetworkController()) << tr("Cancel on ") << identifier << "applied";
124 if (it != end) {
124 reply.first->abort();
125 it->first->abort();
125 }
126 }
126 }
127 impl->unlock();
128
129 // auto end = impl->m_NetworkReplyToVariableId.cend();
130 // auto it = std::find_if(impl->m_NetworkReplyToVariableId.cbegin(), end, findReply);
131 // impl->unlock();
132 // if (it != end) {
133 // qCInfo(LOG_NetworkController()) << tr("Cancel on ") << identifier << "applied";
134 // it->first->abort();
135 // }
127 qCDebug(LOG_NetworkController())
136 qCDebug(LOG_NetworkController())
128 << tr("NetworkController onReplyCanceled END") << QThread::currentThread();
137 << tr("NetworkController onReplyCanceled END") << QThread::currentThread();
129 }
138 }
130
139
131 void NetworkController::waitForFinish()
140 void NetworkController::waitForFinish()
132 {
141 {
133 QMutexLocker locker{&impl->m_WorkingMutex};
142 QMutexLocker locker{&impl->m_WorkingMutex};
134 }
143 }
@@ -1,238 +1,225
1 #include "Variable/VariableAcquisitionWorker.h"
1 #include "Variable/VariableAcquisitionWorker.h"
2
2
3 #include "Variable/Variable.h"
3 #include "Variable/Variable.h"
4
4
5 #include <Data/AcquisitionRequest.h>
5 #include <Data/AcquisitionRequest.h>
6 #include <Data/SqpRange.h>
6 #include <Data/SqpRange.h>
7
7
8 #include <unordered_map>
8 #include <unordered_map>
9 #include <utility>
9 #include <utility>
10
10
11 #include <QMutex>
11 #include <QMutex>
12 #include <QReadWriteLock>
12 #include <QReadWriteLock>
13 #include <QThread>
13 #include <QThread>
14 #include <QtConcurrent/QtConcurrent>
14
15
15 Q_LOGGING_CATEGORY(LOG_VariableAcquisitionWorker, "VariableAcquisitionWorker")
16 Q_LOGGING_CATEGORY(LOG_VariableAcquisitionWorker, "VariableAcquisitionWorker")
16
17
18 namespace {
19
20 using AcquisitionId = QUuid;
21 using VariableId = QUuid;
22
23 } // namespace
24
17 struct VariableAcquisitionWorker::VariableAcquisitionWorkerPrivate {
25 struct VariableAcquisitionWorker::VariableAcquisitionWorkerPrivate {
18
26
19 explicit VariableAcquisitionWorkerPrivate() : m_Lock{QReadWriteLock::Recursive} {}
27 explicit VariableAcquisitionWorkerPrivate() : m_Lock{QReadWriteLock::Recursive} {}
20
28
21 void lockRead() { m_Lock.lockForRead(); }
29 void lockRead() { m_Lock.lockForRead(); }
22 void lockWrite() { m_Lock.lockForWrite(); }
30 void lockWrite() { m_Lock.lockForWrite(); }
23 void unlock() { m_Lock.unlock(); }
31 void unlock() { m_Lock.unlock(); }
24
32
33 void eraseRequest(AcquisitionId id);
34 std::map<AcquisitionId, AcquisitionRequest>::iterator insertRequest(AcquisitionId id,
35 AcquisitionRequest request);
36
25 void removeVariableRequest(QUuid vIdentifier);
37 void removeVariableRequest(QUuid vIdentifier);
26
38
27 QMutex m_WorkingMutex;
39 QMutex m_WorkingMutex;
28 QReadWriteLock m_Lock;
40 QReadWriteLock m_Lock;
29
41
30 std::map<QUuid, QVector<AcquisitionDataPacket> > m_AcqIdentifierToAcqDataPacketVectorMap;
42 /// Current acquisitions (by variable)
31 std::map<QUuid, AcquisitionRequest> m_AcqIdentifierToAcqRequestMap;
43 std::map<AcquisitionId, AcquisitionRequest> m_Requests;
32 std::map<QUuid, std::pair<QUuid, QUuid> > m_VIdentifierToCurrrentAcqIdNextIdPairMap;
44 std::map<VariableId, AcquisitionRequest *> m_RequestsIndex;
33 };
45 };
34
46
35
47
36 VariableAcquisitionWorker::VariableAcquisitionWorker(QObject *parent)
48 VariableAcquisitionWorker::VariableAcquisitionWorker(QObject *parent)
37 : QObject{parent}, impl{spimpl::make_unique_impl<VariableAcquisitionWorkerPrivate>()}
49 : QObject{parent}, impl{spimpl::make_unique_impl<VariableAcquisitionWorkerPrivate>()}
38 {
50 {
39 }
51 }
40
52
41 VariableAcquisitionWorker::~VariableAcquisitionWorker()
53 VariableAcquisitionWorker::~VariableAcquisitionWorker()
42 {
54 {
43 qCInfo(LOG_VariableAcquisitionWorker())
55 qCInfo(LOG_VariableAcquisitionWorker())
44 << tr("VariableAcquisitionWorker destruction") << QThread::currentThread();
56 << tr("VariableAcquisitionWorker destruction") << QThread::currentThread();
45 this->waitForFinish();
57 this->waitForFinish();
46 }
58 }
47
59
48
60
49 QUuid VariableAcquisitionWorker::pushVariableRequest(QUuid varRequestId, QUuid vIdentifier,
61 QUuid VariableAcquisitionWorker::pushVariableRequest(QUuid varRequestId, QUuid vIdentifier,
50 SqpRange rangeRequested,
62 SqpRange rangeRequested,
51 SqpRange cacheRangeRequested,
63 SqpRange cacheRangeRequested,
52 DataProviderParameters parameters,
64 DataProviderParameters parameters,
53 std::shared_ptr<IDataProvider> provider)
65 std::shared_ptr<IDataProvider> provider)
54 {
66 {
55 qCDebug(LOG_VariableAcquisitionWorker())
67 qCDebug(LOG_VariableAcquisitionWorker())
56 << tr("TORM VariableAcquisitionWorker::pushVariableRequest ") << cacheRangeRequested;
68 << tr("TORM VariableAcquisitionWorker::pushVariableRequest ") << cacheRangeRequested;
57 auto varRequestIdCanceled = QUuid();
69 auto varRequestIdCanceled = QUuid();
58
70
59 // Request creation
71 // Request creation
60 auto acqRequest = AcquisitionRequest{};
72 auto acqRequest = AcquisitionRequest{};
61 acqRequest.m_VarRequestId = varRequestId;
73 acqRequest.m_VarRequestId = varRequestId;
62 acqRequest.m_vIdentifier = vIdentifier;
74 acqRequest.m_vIdentifier = vIdentifier;
63 acqRequest.m_DataProviderParameters = parameters;
75 acqRequest.m_DataProviderParameters = parameters;
64 acqRequest.m_RangeRequested = rangeRequested;
76 acqRequest.m_RangeRequested = rangeRequested;
65 acqRequest.m_CacheRangeRequested = cacheRangeRequested;
77 acqRequest.m_CacheRangeRequested = cacheRangeRequested;
66 acqRequest.m_Size = parameters.m_Times.size();
78 acqRequest.m_Size = parameters.m_Times.size();
67 acqRequest.m_Provider = provider;
79 acqRequest.m_Provider = provider;
68
80
69
70 // Register request
71 impl->lockWrite();
81 impl->lockWrite();
72 impl->m_AcqIdentifierToAcqRequestMap.insert(
73 std::make_pair(acqRequest.m_AcqIdentifier, acqRequest));
74
75 auto it = impl->m_VIdentifierToCurrrentAcqIdNextIdPairMap.find(vIdentifier);
76 if (it != impl->m_VIdentifierToCurrrentAcqIdNextIdPairMap.cend()) {
77 // A current request already exists, we can replace the next one
78 auto nextAcqId = it->second.second;
79 auto acqIdentifierToAcqRequestMapIt = impl->m_AcqIdentifierToAcqRequestMap.find(nextAcqId);
80 if (acqIdentifierToAcqRequestMapIt != impl->m_AcqIdentifierToAcqRequestMap.cend()) {
81 auto request = acqIdentifierToAcqRequestMapIt->second;
82 varRequestIdCanceled = request.m_VarRequestId;
83 }
84
82
85 it->second.second = acqRequest.m_AcqIdentifier;
83 // Checks if there is a current acquisition on variable
86 impl->unlock();
84 auto currentRequestIt = impl->m_RequestsIndex.find(vIdentifier);
85 if (currentRequestIt != impl->m_RequestsIndex.cend()) {
86 auto request = currentRequestIt->second;
87 QtConcurrent::run(
88 [ provider = request->m_Provider, acqIdentifier = request->m_AcqIdentifier ]() {
89 provider->requestDataAborting(acqIdentifier);
90 });
91 varRequestIdCanceled = request->m_VarRequestId;
92
93 impl->eraseRequest(request->m_AcqIdentifier);
87 }
94 }
88 else {
89 // First request for the variable, it must be stored and executed
90 impl->m_VIdentifierToCurrrentAcqIdNextIdPairMap.insert(
91 std::make_pair(vIdentifier, std::make_pair(acqRequest.m_AcqIdentifier, QUuid())));
92 impl->unlock();
93
95
96 // Sets the new acquisition request as the current request for the variable
97 auto newRequestIt = impl->insertRequest(acqRequest.m_AcqIdentifier, std::move(acqRequest));
98 if (newRequestIt != impl->m_Requests.end()) {
99 qCInfo(LOG_VariableAcquisitionWorker()) << "EXECUTE REQUEST" << acqRequest.m_AcqIdentifier;
94 QMetaObject::invokeMethod(this, "onExecuteRequest", Qt::QueuedConnection,
100 QMetaObject::invokeMethod(this, "onExecuteRequest", Qt::QueuedConnection,
95 Q_ARG(QUuid, acqRequest.m_AcqIdentifier));
101 Q_ARG(QUuid, newRequestIt->first));
96 }
102 }
103 else {
104 /// @todo ALX : log
105 }
106
107 impl->unlock();
97
108
98 return varRequestIdCanceled;
109 return varRequestIdCanceled;
99 }
110 }
100
111
101 void VariableAcquisitionWorker::abortProgressRequested(QUuid vIdentifier)
112 void VariableAcquisitionWorker::abortProgressRequested(QUuid vIdentifier)
102 {
113 {
103 // TODO
114 // TODO
104 }
115 }
105
116
106 void VariableAcquisitionWorker::onVariableRetrieveDataInProgress(QUuid acqIdentifier,
117 void VariableAcquisitionWorker::onVariableRetrieveDataInProgress(QUuid acqIdentifier,
107 double progress)
118 double progress)
108 {
119 {
109 // TODO
120 // TODO
110 }
121 }
111
122
112 void VariableAcquisitionWorker::onVariableDataAcquired(QUuid acqIdentifier,
123 void VariableAcquisitionWorker::onVariableDataAcquired(QUuid acqIdentifier,
113 std::shared_ptr<IDataSeries> dataSeries,
124 std::shared_ptr<IDataSeries> dataSeries,
114 SqpRange dataRangeAcquired)
125 SqpRange dataRangeAcquired)
115 {
126 {
116 qCDebug(LOG_VariableAcquisitionWorker())
127 qCDebug(LOG_VariableAcquisitionWorker())
117 << tr("onVariableDataAcquired on range ") << acqIdentifier << dataRangeAcquired;
128 << tr("onVariableDataAcquired on range ") << acqIdentifier << dataRangeAcquired;
118 impl->lockWrite();
129 impl->lockWrite();
119 auto aIdToARit = impl->m_AcqIdentifierToAcqRequestMap.find(acqIdentifier);
120 if (aIdToARit != impl->m_AcqIdentifierToAcqRequestMap.cend()) {
121 // Store the result
122 auto dataPacket = AcquisitionDataPacket{};
123 dataPacket.m_Range = dataRangeAcquired;
124 dataPacket.m_DateSeries = dataSeries;
125
126 auto aIdToADPVit = impl->m_AcqIdentifierToAcqDataPacketVectorMap.find(acqIdentifier);
127 if (aIdToADPVit != impl->m_AcqIdentifierToAcqDataPacketVectorMap.cend()) {
128 // A current request result already exists, we can update it
129 aIdToADPVit->second.push_back(dataPacket);
130 }
131 else {
132 // First request result for the variable, it must be stored
133 impl->m_AcqIdentifierToAcqDataPacketVectorMap.insert(
134 std::make_pair(acqIdentifier, QVector<AcquisitionDataPacket>() << dataPacket));
135 }
136
130
131 auto it = impl->m_Requests.find(acqIdentifier);
132 if (it != impl->m_Requests.cend()) {
133 auto &request = it->second;
137
134
138 // Decrement the counter of the request
135 // Store the result
139 auto &acqRequest = aIdToARit->second;
136 auto dataPacket = AcquisitionDataPacket{dataSeries, dataRangeAcquired};
140 acqRequest.m_Size = acqRequest.m_Size - 1;
137 request.m_DataPackets.push_back(dataPacket);
141
138 request.m_Size = request.m_Size - 1;
142 // if the counter is 0, we can return data then run the next request if it exists and
139
143 // removed the finished request
140 if (request.m_Size == 0) {
144 if (acqRequest.m_Size == 0) {
141 emit dataProvided(request.m_vIdentifier, request.m_RangeRequested,
145 // Return the data
142 request.m_CacheRangeRequested, request.m_DataPackets);
146 aIdToADPVit = impl->m_AcqIdentifierToAcqDataPacketVectorMap.find(acqIdentifier);
143 impl->eraseRequest(acqIdentifier);
147 if (aIdToADPVit != impl->m_AcqIdentifierToAcqDataPacketVectorMap.cend()) {
148 emit dataProvided(acqRequest.m_vIdentifier, acqRequest.m_RangeRequested,
149 acqRequest.m_CacheRangeRequested, aIdToADPVit->second);
150 }
151
152 // Execute the next one
153 auto it
154 = impl->m_VIdentifierToCurrrentAcqIdNextIdPairMap.find(acqRequest.m_vIdentifier);
155
156 if (it != impl->m_VIdentifierToCurrrentAcqIdNextIdPairMap.cend()) {
157 if (it->second.second.isNull()) {
158 // There is no next request, we can remove the variable request
159 impl->removeVariableRequest(acqRequest.m_vIdentifier);
160 }
161 else {
162 auto acqIdentifierToRemove = it->second.first;
163 // Move the next request to the current request
164 it->second.first = it->second.second;
165 it->second.second = QUuid();
166 // Remove AcquisitionRequest and results;
167 impl->m_AcqIdentifierToAcqRequestMap.erase(acqIdentifierToRemove);
168 impl->m_AcqIdentifierToAcqDataPacketVectorMap.erase(acqIdentifierToRemove);
169 // Execute the current request
170 QMetaObject::invokeMethod(this, "onExecuteRequest", Qt::QueuedConnection,
171 Q_ARG(QUuid, it->second.first));
172 }
173 }
174 else {
175 qCCritical(LOG_VariableAcquisitionWorker())
176 << tr("Impossible to execute the acquisition on an unfound variable ");
177 }
178 }
144 }
179 }
145 }
180 else {
146 impl->unlock();
181 qCCritical(LOG_VariableAcquisitionWorker())
147 }
182 << tr("Impossible to retrieve AcquisitionRequest for the incoming data");
148
183 }
149 void VariableAcquisitionWorker::onVariableAcquisitionCanceled(QUuid acqIdentifier)
150 {
151 impl->lockWrite();
184 impl->unlock();
152 impl->unlock();
185 }
153 }
186
154
187 void VariableAcquisitionWorker::initialize()
155 void VariableAcquisitionWorker::initialize()
188 {
156 {
189 qCDebug(LOG_VariableAcquisitionWorker())
157 qCDebug(LOG_VariableAcquisitionWorker())
190 << tr("VariableAcquisitionWorker init") << QThread::currentThread();
158 << tr("VariableAcquisitionWorker init") << QThread::currentThread();
191 impl->m_WorkingMutex.lock();
159 impl->m_WorkingMutex.lock();
192 qCDebug(LOG_VariableAcquisitionWorker()) << tr("VariableAcquisitionWorker init END");
160 qCDebug(LOG_VariableAcquisitionWorker()) << tr("VariableAcquisitionWorker init END");
193 }
161 }
194
162
195 void VariableAcquisitionWorker::finalize()
163 void VariableAcquisitionWorker::finalize()
196 {
164 {
197 impl->m_WorkingMutex.unlock();
165 impl->m_WorkingMutex.unlock();
198 }
166 }
199
167
200 void VariableAcquisitionWorker::waitForFinish()
168 void VariableAcquisitionWorker::waitForFinish()
201 {
169 {
202 QMutexLocker locker{&impl->m_WorkingMutex};
170 QMutexLocker locker{&impl->m_WorkingMutex};
203 }
171 }
204
172
205 void VariableAcquisitionWorker::VariableAcquisitionWorkerPrivate::removeVariableRequest(
173
206 QUuid vIdentifier)
174 void VariableAcquisitionWorker::VariableAcquisitionWorkerPrivate::eraseRequest(AcquisitionId id)
207 {
175 {
208 lockWrite();
176 auto it = m_Requests.find(id);
209 auto it = m_VIdentifierToCurrrentAcqIdNextIdPairMap.find(vIdentifier);
177 if (it != m_Requests.end()) {
178 // Removes from index
179 m_RequestsIndex.erase(it->second.m_vIdentifier);
210
180
211 if (it != m_VIdentifierToCurrrentAcqIdNextIdPairMap.cend()) {
181 // Removes request
212 // A current request already exists, we can replace the next one
182 m_Requests.erase(it);
183 }
184 }
213
185
214 m_AcqIdentifierToAcqRequestMap.erase(it->second.first);
186 std::map<AcquisitionId, AcquisitionRequest>::iterator
215 m_AcqIdentifierToAcqDataPacketVectorMap.erase(it->second.first);
187 VariableAcquisitionWorker::VariableAcquisitionWorkerPrivate::insertRequest(
188 AcquisitionId id, AcquisitionRequest request)
189 {
190 // Inserts request
191 auto variableId = request.m_vIdentifier;
192 auto result = m_Requests.insert(std::make_pair(id, std::move(request)));
193
194 if (result.second) {
195 // Inserts index
196 m_RequestsIndex[variableId] = &result.first->second;
216
197
217 m_AcqIdentifierToAcqRequestMap.erase(it->second.second);
198 return result.first;
218 m_AcqIdentifierToAcqDataPacketVectorMap.erase(it->second.second);
219 }
199 }
220 m_VIdentifierToCurrrentAcqIdNextIdPairMap.erase(vIdentifier);
200 else {
221 unlock();
201 return m_Requests.end();
202 }
203 }
204
205 void VariableAcquisitionWorker::VariableAcquisitionWorkerPrivate::removeVariableRequest(
206 QUuid vIdentifier)
207 {
208 /// @todo ALX
209 // m_Acquisitions.erase(vIdentifier);
222 }
210 }
223
211
224 void VariableAcquisitionWorker::onExecuteRequest(QUuid acqIdentifier)
212 void VariableAcquisitionWorker::onExecuteRequest(QUuid acqIdentifier)
225 {
213 {
226 qCDebug(LOG_VariableAcquisitionWorker()) << tr("onExecuteRequest") << QThread::currentThread();
227 impl->lockRead();
214 impl->lockRead();
228 auto it = impl->m_AcqIdentifierToAcqRequestMap.find(acqIdentifier);
215 auto it = impl->m_Requests.find(acqIdentifier);
229 if (it != impl->m_AcqIdentifierToAcqRequestMap.cend()) {
216 if (it != impl->m_Requests.cend()) {
230 auto request = it->second;
217 auto &request = it->second;
231 impl->unlock();
218 impl->unlock();
232 request.m_Provider->requestDataLoading(acqIdentifier, request.m_DataProviderParameters);
219 request.m_Provider->requestDataLoading(acqIdentifier, request.m_DataProviderParameters);
233 }
220 }
234 else {
221 else {
235 impl->unlock();
222 impl->unlock();
236 // TODO log no acqIdentifier recognized
223 // TODO log no acqIdentifier recognized
237 }
224 }
238 }
225 }
@@ -1,805 +1,806
1 #include <Variable/Variable.h>
1 #include <Variable/Variable.h>
2 #include <Variable/VariableAcquisitionWorker.h>
2 #include <Variable/VariableAcquisitionWorker.h>
3 #include <Variable/VariableCacheStrategy.h>
3 #include <Variable/VariableCacheStrategy.h>
4 #include <Variable/VariableController.h>
4 #include <Variable/VariableController.h>
5 #include <Variable/VariableModel.h>
5 #include <Variable/VariableModel.h>
6 #include <Variable/VariableSynchronizationGroup.h>
6 #include <Variable/VariableSynchronizationGroup.h>
7
7
8 #include <Data/DataProviderParameters.h>
8 #include <Data/DataProviderParameters.h>
9 #include <Data/IDataProvider.h>
9 #include <Data/IDataProvider.h>
10 #include <Data/IDataSeries.h>
10 #include <Data/IDataSeries.h>
11 #include <Data/VariableRequest.h>
11 #include <Data/VariableRequest.h>
12 #include <Time/TimeController.h>
12 #include <Time/TimeController.h>
13
13
14 #include <QMutex>
14 #include <QMutex>
15 #include <QThread>
15 #include <QThread>
16 #include <QUuid>
16 #include <QUuid>
17 #include <QtCore/QItemSelectionModel>
17 #include <QtCore/QItemSelectionModel>
18
18
19 #include <deque>
19 #include <deque>
20 #include <set>
20 #include <set>
21 #include <unordered_map>
21 #include <unordered_map>
22
22
23 Q_LOGGING_CATEGORY(LOG_VariableController, "VariableController")
23 Q_LOGGING_CATEGORY(LOG_VariableController, "VariableController")
24
24
25 namespace {
25 namespace {
26
26
27 SqpRange computeSynchroRangeRequested(const SqpRange &varRange, const SqpRange &graphRange,
27 SqpRange computeSynchroRangeRequested(const SqpRange &varRange, const SqpRange &graphRange,
28 const SqpRange &oldGraphRange)
28 const SqpRange &oldGraphRange)
29 {
29 {
30 auto zoomType = VariableController::getZoomType(graphRange, oldGraphRange);
30 auto zoomType = VariableController::getZoomType(graphRange, oldGraphRange);
31
31
32 auto varRangeRequested = varRange;
32 auto varRangeRequested = varRange;
33 switch (zoomType) {
33 switch (zoomType) {
34 case AcquisitionZoomType::ZoomIn: {
34 case AcquisitionZoomType::ZoomIn: {
35 auto deltaLeft = graphRange.m_TStart - oldGraphRange.m_TStart;
35 auto deltaLeft = graphRange.m_TStart - oldGraphRange.m_TStart;
36 auto deltaRight = oldGraphRange.m_TEnd - graphRange.m_TEnd;
36 auto deltaRight = oldGraphRange.m_TEnd - graphRange.m_TEnd;
37 varRangeRequested.m_TStart += deltaLeft;
37 varRangeRequested.m_TStart += deltaLeft;
38 varRangeRequested.m_TEnd -= deltaRight;
38 varRangeRequested.m_TEnd -= deltaRight;
39 break;
39 break;
40 }
40 }
41
41
42 case AcquisitionZoomType::ZoomOut: {
42 case AcquisitionZoomType::ZoomOut: {
43 auto deltaLeft = oldGraphRange.m_TStart - graphRange.m_TStart;
43 auto deltaLeft = oldGraphRange.m_TStart - graphRange.m_TStart;
44 auto deltaRight = graphRange.m_TEnd - oldGraphRange.m_TEnd;
44 auto deltaRight = graphRange.m_TEnd - oldGraphRange.m_TEnd;
45 varRangeRequested.m_TStart -= deltaLeft;
45 varRangeRequested.m_TStart -= deltaLeft;
46 varRangeRequested.m_TEnd += deltaRight;
46 varRangeRequested.m_TEnd += deltaRight;
47 break;
47 break;
48 }
48 }
49 case AcquisitionZoomType::PanRight: {
49 case AcquisitionZoomType::PanRight: {
50 auto deltaRight = graphRange.m_TEnd - oldGraphRange.m_TEnd;
50 auto deltaRight = graphRange.m_TEnd - oldGraphRange.m_TEnd;
51 varRangeRequested.m_TStart += deltaRight;
51 varRangeRequested.m_TStart += deltaRight;
52 varRangeRequested.m_TEnd += deltaRight;
52 varRangeRequested.m_TEnd += deltaRight;
53 break;
53 break;
54 }
54 }
55 case AcquisitionZoomType::PanLeft: {
55 case AcquisitionZoomType::PanLeft: {
56 auto deltaLeft = oldGraphRange.m_TStart - graphRange.m_TStart;
56 auto deltaLeft = oldGraphRange.m_TStart - graphRange.m_TStart;
57 varRangeRequested.m_TStart -= deltaLeft;
57 varRangeRequested.m_TStart -= deltaLeft;
58 varRangeRequested.m_TEnd -= deltaLeft;
58 varRangeRequested.m_TEnd -= deltaLeft;
59 break;
59 break;
60 }
60 }
61 case AcquisitionZoomType::Unknown: {
61 case AcquisitionZoomType::Unknown: {
62 qCCritical(LOG_VariableController())
62 qCCritical(LOG_VariableController())
63 << VariableController::tr("Impossible to synchronize: zoom type unknown");
63 << VariableController::tr("Impossible to synchronize: zoom type unknown");
64 break;
64 break;
65 }
65 }
66 default:
66 default:
67 qCCritical(LOG_VariableController()) << VariableController::tr(
67 qCCritical(LOG_VariableController()) << VariableController::tr(
68 "Impossible to synchronize: zoom type not take into account");
68 "Impossible to synchronize: zoom type not take into account");
69 // No action
69 // No action
70 break;
70 break;
71 }
71 }
72
72
73 return varRangeRequested;
73 return varRangeRequested;
74 }
74 }
75 }
75 }
76
76
77 struct VariableController::VariableControllerPrivate {
77 struct VariableController::VariableControllerPrivate {
78 explicit VariableControllerPrivate(VariableController *parent)
78 explicit VariableControllerPrivate(VariableController *parent)
79 : m_WorkingMutex{},
79 : m_WorkingMutex{},
80 m_VariableModel{new VariableModel{parent}},
80 m_VariableModel{new VariableModel{parent}},
81 m_VariableSelectionModel{new QItemSelectionModel{m_VariableModel, parent}},
81 m_VariableSelectionModel{new QItemSelectionModel{m_VariableModel, parent}},
82 m_VariableCacheStrategy{std::make_unique<VariableCacheStrategy>()},
82 m_VariableCacheStrategy{std::make_unique<VariableCacheStrategy>()},
83 m_VariableAcquisitionWorker{std::make_unique<VariableAcquisitionWorker>()},
83 m_VariableAcquisitionWorker{std::make_unique<VariableAcquisitionWorker>()},
84 q{parent}
84 q{parent}
85 {
85 {
86
86
87 m_VariableAcquisitionWorker->moveToThread(&m_VariableAcquisitionWorkerThread);
87 m_VariableAcquisitionWorker->moveToThread(&m_VariableAcquisitionWorkerThread);
88 m_VariableAcquisitionWorkerThread.setObjectName("VariableAcquisitionWorkerThread");
88 m_VariableAcquisitionWorkerThread.setObjectName("VariableAcquisitionWorkerThread");
89 }
89 }
90
90
91
91
92 virtual ~VariableControllerPrivate()
92 virtual ~VariableControllerPrivate()
93 {
93 {
94 qCDebug(LOG_VariableController()) << tr("VariableControllerPrivate destruction");
94 qCDebug(LOG_VariableController()) << tr("VariableControllerPrivate destruction");
95 m_VariableAcquisitionWorkerThread.quit();
95 m_VariableAcquisitionWorkerThread.quit();
96 m_VariableAcquisitionWorkerThread.wait();
96 m_VariableAcquisitionWorkerThread.wait();
97 }
97 }
98
98
99
99
100 void processRequest(std::shared_ptr<Variable> var, const SqpRange &rangeRequested,
100 void processRequest(std::shared_ptr<Variable> var, const SqpRange &rangeRequested,
101 QUuid varRequestId);
101 QUuid varRequestId);
102
102
103 QVector<SqpRange> provideNotInCacheDateTimeList(std::shared_ptr<Variable> variable,
103 QVector<SqpRange> provideNotInCacheDateTimeList(std::shared_ptr<Variable> variable,
104 const SqpRange &dateTime);
104 const SqpRange &dateTime);
105
105
106 std::shared_ptr<Variable> findVariable(QUuid vIdentifier);
106 std::shared_ptr<Variable> findVariable(QUuid vIdentifier);
107 std::shared_ptr<IDataSeries>
107 std::shared_ptr<IDataSeries>
108 retrieveDataSeries(const QVector<AcquisitionDataPacket> acqDataPacketVector);
108 retrieveDataSeries(const QVector<AcquisitionDataPacket> acqDataPacketVector);
109
109
110 void registerProvider(std::shared_ptr<IDataProvider> provider);
110 void registerProvider(std::shared_ptr<IDataProvider> provider);
111
111
112 void storeVariableRequest(QUuid varId, QUuid varRequestId, const VariableRequest &varRequest);
112 void storeVariableRequest(QUuid varId, QUuid varRequestId, const VariableRequest &varRequest);
113 QUuid acceptVariableRequest(QUuid varId, std::shared_ptr<IDataSeries> dataSeries);
113 QUuid acceptVariableRequest(QUuid varId, std::shared_ptr<IDataSeries> dataSeries);
114 void updateVariableRequest(QUuid varRequestId);
114 void updateVariableRequest(QUuid varRequestId);
115 void cancelVariableRequest(QUuid varRequestId);
115 void cancelVariableRequest(QUuid varRequestId);
116
116
117 QMutex m_WorkingMutex;
117 QMutex m_WorkingMutex;
118 /// Variable model. The VariableController has the ownership
118 /// Variable model. The VariableController has the ownership
119 VariableModel *m_VariableModel;
119 VariableModel *m_VariableModel;
120 QItemSelectionModel *m_VariableSelectionModel;
120 QItemSelectionModel *m_VariableSelectionModel;
121
121
122
122
123 TimeController *m_TimeController{nullptr};
123 TimeController *m_TimeController{nullptr};
124 std::unique_ptr<VariableCacheStrategy> m_VariableCacheStrategy;
124 std::unique_ptr<VariableCacheStrategy> m_VariableCacheStrategy;
125 std::unique_ptr<VariableAcquisitionWorker> m_VariableAcquisitionWorker;
125 std::unique_ptr<VariableAcquisitionWorker> m_VariableAcquisitionWorker;
126 QThread m_VariableAcquisitionWorkerThread;
126 QThread m_VariableAcquisitionWorkerThread;
127
127
128 std::unordered_map<std::shared_ptr<Variable>, std::shared_ptr<IDataProvider> >
128 std::unordered_map<std::shared_ptr<Variable>, std::shared_ptr<IDataProvider> >
129 m_VariableToProviderMap;
129 m_VariableToProviderMap;
130 std::unordered_map<std::shared_ptr<Variable>, QUuid> m_VariableToIdentifierMap;
130 std::unordered_map<std::shared_ptr<Variable>, QUuid> m_VariableToIdentifierMap;
131 std::map<QUuid, std::shared_ptr<VariableSynchronizationGroup> >
131 std::map<QUuid, std::shared_ptr<VariableSynchronizationGroup> >
132 m_GroupIdToVariableSynchronizationGroupMap;
132 m_GroupIdToVariableSynchronizationGroupMap;
133 std::map<QUuid, QUuid> m_VariableIdGroupIdMap;
133 std::map<QUuid, QUuid> m_VariableIdGroupIdMap;
134 std::set<std::shared_ptr<IDataProvider> > m_ProviderSet;
134 std::set<std::shared_ptr<IDataProvider> > m_ProviderSet;
135
135
136 std::map<QUuid, std::map<QUuid, VariableRequest> > m_VarRequestIdToVarIdVarRequestMap;
136 std::map<QUuid, std::map<QUuid, VariableRequest> > m_VarRequestIdToVarIdVarRequestMap;
137
137
138 std::map<QUuid, std::deque<QUuid> > m_VarIdToVarRequestIdQueueMap;
138 std::map<QUuid, std::deque<QUuid> > m_VarIdToVarRequestIdQueueMap;
139
139
140
140
141 VariableController *q;
141 VariableController *q;
142 };
142 };
143
143
144
144
145 VariableController::VariableController(QObject *parent)
145 VariableController::VariableController(QObject *parent)
146 : QObject{parent}, impl{spimpl::make_unique_impl<VariableControllerPrivate>(this)}
146 : QObject{parent}, impl{spimpl::make_unique_impl<VariableControllerPrivate>(this)}
147 {
147 {
148 qCDebug(LOG_VariableController())
148 qCDebug(LOG_VariableController())
149 << tr("VariableController construction") << QThread::currentThread();
149 << tr("VariableController construction") << QThread::currentThread();
150
150
151 connect(impl->m_VariableModel, &VariableModel::abortProgessRequested, this,
151 connect(impl->m_VariableModel, &VariableModel::abortProgessRequested, this,
152 &VariableController::onAbortProgressRequested);
152 &VariableController::onAbortProgressRequested);
153
153
154 connect(impl->m_VariableAcquisitionWorker.get(), &VariableAcquisitionWorker::dataProvided, this,
154 connect(impl->m_VariableAcquisitionWorker.get(), &VariableAcquisitionWorker::dataProvided, this,
155 &VariableController::onDataProvided);
155 &VariableController::onDataProvided);
156 connect(impl->m_VariableAcquisitionWorker.get(),
156 connect(impl->m_VariableAcquisitionWorker.get(),
157 &VariableAcquisitionWorker::variableRequestInProgress, this,
157 &VariableAcquisitionWorker::variableRequestInProgress, this,
158 &VariableController::onVariableRetrieveDataInProgress);
158 &VariableController::onVariableRetrieveDataInProgress);
159
159
160 connect(&impl->m_VariableAcquisitionWorkerThread, &QThread::started,
160 connect(&impl->m_VariableAcquisitionWorkerThread, &QThread::started,
161 impl->m_VariableAcquisitionWorker.get(), &VariableAcquisitionWorker::initialize);
161 impl->m_VariableAcquisitionWorker.get(), &VariableAcquisitionWorker::initialize);
162 connect(&impl->m_VariableAcquisitionWorkerThread, &QThread::finished,
162 connect(&impl->m_VariableAcquisitionWorkerThread, &QThread::finished,
163 impl->m_VariableAcquisitionWorker.get(), &VariableAcquisitionWorker::finalize);
163 impl->m_VariableAcquisitionWorker.get(), &VariableAcquisitionWorker::finalize);
164
164
165
165
166 impl->m_VariableAcquisitionWorkerThread.start();
166 impl->m_VariableAcquisitionWorkerThread.start();
167 }
167 }
168
168
169 VariableController::~VariableController()
169 VariableController::~VariableController()
170 {
170 {
171 qCDebug(LOG_VariableController())
171 qCDebug(LOG_VariableController())
172 << tr("VariableController destruction") << QThread::currentThread();
172 << tr("VariableController destruction") << QThread::currentThread();
173 this->waitForFinish();
173 this->waitForFinish();
174 }
174 }
175
175
176 VariableModel *VariableController::variableModel() noexcept
176 VariableModel *VariableController::variableModel() noexcept
177 {
177 {
178 return impl->m_VariableModel;
178 return impl->m_VariableModel;
179 }
179 }
180
180
181 QItemSelectionModel *VariableController::variableSelectionModel() noexcept
181 QItemSelectionModel *VariableController::variableSelectionModel() noexcept
182 {
182 {
183 return impl->m_VariableSelectionModel;
183 return impl->m_VariableSelectionModel;
184 }
184 }
185
185
186 void VariableController::setTimeController(TimeController *timeController) noexcept
186 void VariableController::setTimeController(TimeController *timeController) noexcept
187 {
187 {
188 impl->m_TimeController = timeController;
188 impl->m_TimeController = timeController;
189 }
189 }
190
190
191 std::shared_ptr<Variable>
191 std::shared_ptr<Variable>
192 VariableController::cloneVariable(std::shared_ptr<Variable> variable) noexcept
192 VariableController::cloneVariable(std::shared_ptr<Variable> variable) noexcept
193 {
193 {
194 if (impl->m_VariableModel->containsVariable(variable)) {
194 if (impl->m_VariableModel->containsVariable(variable)) {
195 // Clones variable
195 // Clones variable
196 auto duplicate = variable->clone();
196 auto duplicate = variable->clone();
197
197
198 // Adds clone to model
198 // Adds clone to model
199 impl->m_VariableModel->addVariable(duplicate);
199 impl->m_VariableModel->addVariable(duplicate);
200
200
201 // Generates clone identifier
201 // Generates clone identifier
202 impl->m_VariableToIdentifierMap[duplicate] = QUuid::createUuid();
202 impl->m_VariableToIdentifierMap[duplicate] = QUuid::createUuid();
203
203
204 // Registers provider
204 // Registers provider
205 auto variableProvider = impl->m_VariableToProviderMap.at(variable);
205 auto variableProvider = impl->m_VariableToProviderMap.at(variable);
206 auto duplicateProvider = variableProvider != nullptr ? variableProvider->clone() : nullptr;
206 auto duplicateProvider = variableProvider != nullptr ? variableProvider->clone() : nullptr;
207
207
208 impl->m_VariableToProviderMap[duplicate] = duplicateProvider;
208 impl->m_VariableToProviderMap[duplicate] = duplicateProvider;
209 if (duplicateProvider) {
209 if (duplicateProvider) {
210 impl->registerProvider(duplicateProvider);
210 impl->registerProvider(duplicateProvider);
211 }
211 }
212
212
213 return duplicate;
213 return duplicate;
214 }
214 }
215 else {
215 else {
216 qCCritical(LOG_VariableController())
216 qCCritical(LOG_VariableController())
217 << tr("Can't create duplicate of variable %1: variable not registered in the model")
217 << tr("Can't create duplicate of variable %1: variable not registered in the model")
218 .arg(variable->name());
218 .arg(variable->name());
219 return nullptr;
219 return nullptr;
220 }
220 }
221 }
221 }
222
222
223 void VariableController::deleteVariable(std::shared_ptr<Variable> variable) noexcept
223 void VariableController::deleteVariable(std::shared_ptr<Variable> variable) noexcept
224 {
224 {
225 if (!variable) {
225 if (!variable) {
226 qCCritical(LOG_VariableController()) << "Can't delete variable: variable is null";
226 qCCritical(LOG_VariableController()) << "Can't delete variable: variable is null";
227 return;
227 return;
228 }
228 }
229
229
230 // Spreads in SciQlop that the variable will be deleted, so that potential receivers can
230 // Spreads in SciQlop that the variable will be deleted, so that potential receivers can
231 // make some treatments before the deletion
231 // make some treatments before the deletion
232 emit variableAboutToBeDeleted(variable);
232 emit variableAboutToBeDeleted(variable);
233
233
234 // Deletes identifier
234 // Deletes identifier
235 impl->m_VariableToIdentifierMap.erase(variable);
235 impl->m_VariableToIdentifierMap.erase(variable);
236
236
237 // Deletes provider
237 // Deletes provider
238 auto nbProvidersDeleted = impl->m_VariableToProviderMap.erase(variable);
238 auto nbProvidersDeleted = impl->m_VariableToProviderMap.erase(variable);
239 qCDebug(LOG_VariableController())
239 qCDebug(LOG_VariableController())
240 << tr("Number of providers deleted for variable %1: %2")
240 << tr("Number of providers deleted for variable %1: %2")
241 .arg(variable->name(), QString::number(nbProvidersDeleted));
241 .arg(variable->name(), QString::number(nbProvidersDeleted));
242
242
243
243
244 // Deletes from model
244 // Deletes from model
245 impl->m_VariableModel->deleteVariable(variable);
245 impl->m_VariableModel->deleteVariable(variable);
246 }
246 }
247
247
248 void VariableController::deleteVariables(
248 void VariableController::deleteVariables(
249 const QVector<std::shared_ptr<Variable> > &variables) noexcept
249 const QVector<std::shared_ptr<Variable> > &variables) noexcept
250 {
250 {
251 for (auto variable : qAsConst(variables)) {
251 for (auto variable : qAsConst(variables)) {
252 deleteVariable(variable);
252 deleteVariable(variable);
253 }
253 }
254 }
254 }
255
255
256 void VariableController::abortProgress(std::shared_ptr<Variable> variable)
256 void VariableController::abortProgress(std::shared_ptr<Variable> variable)
257 {
257 {
258 }
258 }
259
259
260 std::shared_ptr<Variable>
260 std::shared_ptr<Variable>
261 VariableController::createVariable(const QString &name, const QVariantHash &metadata,
261 VariableController::createVariable(const QString &name, const QVariantHash &metadata,
262 std::shared_ptr<IDataProvider> provider) noexcept
262 std::shared_ptr<IDataProvider> provider) noexcept
263 {
263 {
264 if (!impl->m_TimeController) {
264 if (!impl->m_TimeController) {
265 qCCritical(LOG_VariableController())
265 qCCritical(LOG_VariableController())
266 << tr("Impossible to create variable: The time controller is null");
266 << tr("Impossible to create variable: The time controller is null");
267 return nullptr;
267 return nullptr;
268 }
268 }
269
269
270 auto range = impl->m_TimeController->dateTime();
270 auto range = impl->m_TimeController->dateTime();
271
271
272 if (auto newVariable = impl->m_VariableModel->createVariable(name, range, metadata)) {
272 if (auto newVariable = impl->m_VariableModel->createVariable(name, range, metadata)) {
273 auto identifier = QUuid::createUuid();
273 auto identifier = QUuid::createUuid();
274
274
275 // store the provider
275 // store the provider
276 impl->registerProvider(provider);
276 impl->registerProvider(provider);
277
277
278 // Associate the provider
278 // Associate the provider
279 impl->m_VariableToProviderMap[newVariable] = provider;
279 impl->m_VariableToProviderMap[newVariable] = provider;
280 impl->m_VariableToIdentifierMap[newVariable] = identifier;
280 impl->m_VariableToIdentifierMap[newVariable] = identifier;
281
281
282
282
283 auto varRequestId = QUuid::createUuid();
283 auto varRequestId = QUuid::createUuid();
284 qCInfo(LOG_VariableController()) << "processRequest for" << name << varRequestId;
284 qCInfo(LOG_VariableController()) << "processRequest for" << name << varRequestId;
285 impl->processRequest(newVariable, range, varRequestId);
285 impl->processRequest(newVariable, range, varRequestId);
286 impl->updateVariableRequest(varRequestId);
286 impl->updateVariableRequest(varRequestId);
287
287
288 return newVariable;
288 return newVariable;
289 }
289 }
290 }
290 }
291
291
292 void VariableController::onDateTimeOnSelection(const SqpRange &dateTime)
292 void VariableController::onDateTimeOnSelection(const SqpRange &dateTime)
293 {
293 {
294 // TODO check synchronisation and Rescale
294 // TODO check synchronisation and Rescale
295 qCDebug(LOG_VariableController())
295 qCDebug(LOG_VariableController())
296 << "VariableController::onDateTimeOnSelection" << QThread::currentThread()->objectName();
296 << "VariableController::onDateTimeOnSelection" << QThread::currentThread()->objectName();
297 auto selectedRows = impl->m_VariableSelectionModel->selectedRows();
297 auto selectedRows = impl->m_VariableSelectionModel->selectedRows();
298 auto varRequestId = QUuid::createUuid();
298 auto varRequestId = QUuid::createUuid();
299
299
300 for (const auto &selectedRow : qAsConst(selectedRows)) {
300 for (const auto &selectedRow : qAsConst(selectedRows)) {
301 if (auto selectedVariable = impl->m_VariableModel->variable(selectedRow.row())) {
301 if (auto selectedVariable = impl->m_VariableModel->variable(selectedRow.row())) {
302 selectedVariable->setRange(dateTime);
302 selectedVariable->setRange(dateTime);
303 impl->processRequest(selectedVariable, dateTime, varRequestId);
303 impl->processRequest(selectedVariable, dateTime, varRequestId);
304
304
305 // notify that rescale operation has to be done
305 // notify that rescale operation has to be done
306 emit rangeChanged(selectedVariable, dateTime);
306 emit rangeChanged(selectedVariable, dateTime);
307 }
307 }
308 }
308 }
309 impl->updateVariableRequest(varRequestId);
309 impl->updateVariableRequest(varRequestId);
310 }
310 }
311
311
312 void VariableController::onDataProvided(QUuid vIdentifier, const SqpRange &rangeRequested,
312 void VariableController::onDataProvided(QUuid vIdentifier, const SqpRange &rangeRequested,
313 const SqpRange &cacheRangeRequested,
313 const SqpRange &cacheRangeRequested,
314 QVector<AcquisitionDataPacket> dataAcquired)
314 QVector<AcquisitionDataPacket> dataAcquired)
315 {
315 {
316 qCInfo(LOG_VariableController()) << "VariableController::onDataProvided";
316 auto retrievedDataSeries = impl->retrieveDataSeries(dataAcquired);
317 auto retrievedDataSeries = impl->retrieveDataSeries(dataAcquired);
317 auto varRequestId = impl->acceptVariableRequest(vIdentifier, retrievedDataSeries);
318 auto varRequestId = impl->acceptVariableRequest(vIdentifier, retrievedDataSeries);
318 if (!varRequestId.isNull()) {
319 if (!varRequestId.isNull()) {
319 impl->updateVariableRequest(varRequestId);
320 impl->updateVariableRequest(varRequestId);
320 }
321 }
321 }
322 }
322
323
323 void VariableController::onVariableRetrieveDataInProgress(QUuid identifier, double progress)
324 void VariableController::onVariableRetrieveDataInProgress(QUuid identifier, double progress)
324 {
325 {
325 if (auto var = impl->findVariable(identifier)) {
326 if (auto var = impl->findVariable(identifier)) {
326 impl->m_VariableModel->setDataProgress(var, progress);
327 impl->m_VariableModel->setDataProgress(var, progress);
327 }
328 }
328 else {
329 else {
329 qCCritical(LOG_VariableController())
330 qCCritical(LOG_VariableController())
330 << tr("Impossible to notify progression of a null variable");
331 << tr("Impossible to notify progression of a null variable");
331 }
332 }
332 }
333 }
333
334
334 void VariableController::onAbortProgressRequested(std::shared_ptr<Variable> variable)
335 void VariableController::onAbortProgressRequested(std::shared_ptr<Variable> variable)
335 {
336 {
336 qCDebug(LOG_VariableController()) << "TORM: VariableController::onAbortProgressRequested"
337 qCDebug(LOG_VariableController()) << "TORM: VariableController::onAbortProgressRequested"
337 << QThread::currentThread()->objectName();
338 << QThread::currentThread()->objectName();
338
339
339 auto it = impl->m_VariableToIdentifierMap.find(variable);
340 auto it = impl->m_VariableToIdentifierMap.find(variable);
340 if (it != impl->m_VariableToIdentifierMap.cend()) {
341 if (it != impl->m_VariableToIdentifierMap.cend()) {
341 impl->m_VariableToProviderMap.at(variable)->requestDataAborting(it->second);
342 impl->m_VariableToProviderMap.at(variable)->requestDataAborting(it->second);
342 }
343 }
343 else {
344 else {
344 qCWarning(LOG_VariableController())
345 qCWarning(LOG_VariableController())
345 << tr("Aborting progression of inexistant variable detected !!!")
346 << tr("Aborting progression of inexistant variable detected !!!")
346 << QThread::currentThread()->objectName();
347 << QThread::currentThread()->objectName();
347 }
348 }
348 }
349 }
349
350
350 void VariableController::onAddSynchronizationGroupId(QUuid synchronizationGroupId)
351 void VariableController::onAddSynchronizationGroupId(QUuid synchronizationGroupId)
351 {
352 {
352 qCDebug(LOG_VariableController())
353 qCDebug(LOG_VariableController())
353 << "TORM: VariableController::onAddSynchronizationGroupId"
354 << "TORM: VariableController::onAddSynchronizationGroupId"
354 << QThread::currentThread()->objectName() << synchronizationGroupId;
355 << QThread::currentThread()->objectName() << synchronizationGroupId;
355 auto vSynchroGroup = std::make_shared<VariableSynchronizationGroup>();
356 auto vSynchroGroup = std::make_shared<VariableSynchronizationGroup>();
356 impl->m_GroupIdToVariableSynchronizationGroupMap.insert(
357 impl->m_GroupIdToVariableSynchronizationGroupMap.insert(
357 std::make_pair(synchronizationGroupId, vSynchroGroup));
358 std::make_pair(synchronizationGroupId, vSynchroGroup));
358 }
359 }
359
360
360 void VariableController::onRemoveSynchronizationGroupId(QUuid synchronizationGroupId)
361 void VariableController::onRemoveSynchronizationGroupId(QUuid synchronizationGroupId)
361 {
362 {
362 impl->m_GroupIdToVariableSynchronizationGroupMap.erase(synchronizationGroupId);
363 impl->m_GroupIdToVariableSynchronizationGroupMap.erase(synchronizationGroupId);
363 }
364 }
364
365
365 void VariableController::onAddSynchronized(std::shared_ptr<Variable> variable,
366 void VariableController::onAddSynchronized(std::shared_ptr<Variable> variable,
366 QUuid synchronizationGroupId)
367 QUuid synchronizationGroupId)
367
368
368 {
369 {
369 qCDebug(LOG_VariableController())
370 qCDebug(LOG_VariableController())
370 << "TORM: VariableController::onAddSynchronized" << synchronizationGroupId;
371 << "TORM: VariableController::onAddSynchronized" << synchronizationGroupId;
371 auto varToVarIdIt = impl->m_VariableToIdentifierMap.find(variable);
372 auto varToVarIdIt = impl->m_VariableToIdentifierMap.find(variable);
372 if (varToVarIdIt != impl->m_VariableToIdentifierMap.cend()) {
373 if (varToVarIdIt != impl->m_VariableToIdentifierMap.cend()) {
373 auto groupIdToVSGIt
374 auto groupIdToVSGIt
374 = impl->m_GroupIdToVariableSynchronizationGroupMap.find(synchronizationGroupId);
375 = impl->m_GroupIdToVariableSynchronizationGroupMap.find(synchronizationGroupId);
375 if (groupIdToVSGIt != impl->m_GroupIdToVariableSynchronizationGroupMap.cend()) {
376 if (groupIdToVSGIt != impl->m_GroupIdToVariableSynchronizationGroupMap.cend()) {
376 impl->m_VariableIdGroupIdMap.insert(
377 impl->m_VariableIdGroupIdMap.insert(
377 std::make_pair(varToVarIdIt->second, synchronizationGroupId));
378 std::make_pair(varToVarIdIt->second, synchronizationGroupId));
378 groupIdToVSGIt->second->addVariableId(varToVarIdIt->second);
379 groupIdToVSGIt->second->addVariableId(varToVarIdIt->second);
379 }
380 }
380 else {
381 else {
381 qCCritical(LOG_VariableController())
382 qCCritical(LOG_VariableController())
382 << tr("Impossible to synchronize a variable with an unknown sycnhronization group")
383 << tr("Impossible to synchronize a variable with an unknown sycnhronization group")
383 << variable->name();
384 << variable->name();
384 }
385 }
385 }
386 }
386 else {
387 else {
387 qCCritical(LOG_VariableController())
388 qCCritical(LOG_VariableController())
388 << tr("Impossible to synchronize a variable with no identifier") << variable->name();
389 << tr("Impossible to synchronize a variable with no identifier") << variable->name();
389 }
390 }
390 }
391 }
391
392
392 void VariableController::desynchronize(std::shared_ptr<Variable> variable,
393 void VariableController::desynchronize(std::shared_ptr<Variable> variable,
393 QUuid synchronizationGroupId)
394 QUuid synchronizationGroupId)
394 {
395 {
395 // Gets variable id
396 // Gets variable id
396 auto variableIt = impl->m_VariableToIdentifierMap.find(variable);
397 auto variableIt = impl->m_VariableToIdentifierMap.find(variable);
397 if (variableIt == impl->m_VariableToIdentifierMap.cend()) {
398 if (variableIt == impl->m_VariableToIdentifierMap.cend()) {
398 qCCritical(LOG_VariableController())
399 qCCritical(LOG_VariableController())
399 << tr("Can't desynchronize variable %1: variable identifier not found")
400 << tr("Can't desynchronize variable %1: variable identifier not found")
400 .arg(variable->name());
401 .arg(variable->name());
401 return;
402 return;
402 }
403 }
403
404
404 // Gets synchronization group
405 // Gets synchronization group
405 auto groupIt = impl->m_GroupIdToVariableSynchronizationGroupMap.find(synchronizationGroupId);
406 auto groupIt = impl->m_GroupIdToVariableSynchronizationGroupMap.find(synchronizationGroupId);
406 if (groupIt == impl->m_GroupIdToVariableSynchronizationGroupMap.cend()) {
407 if (groupIt == impl->m_GroupIdToVariableSynchronizationGroupMap.cend()) {
407 qCCritical(LOG_VariableController())
408 qCCritical(LOG_VariableController())
408 << tr("Can't desynchronize variable %1: unknown synchronization group")
409 << tr("Can't desynchronize variable %1: unknown synchronization group")
409 .arg(variable->name());
410 .arg(variable->name());
410 return;
411 return;
411 }
412 }
412
413
413 auto variableId = variableIt->second;
414 auto variableId = variableIt->second;
414
415
415 // Removes variable from synchronization group
416 // Removes variable from synchronization group
416 auto synchronizationGroup = groupIt->second;
417 auto synchronizationGroup = groupIt->second;
417 synchronizationGroup->removeVariableId(variableId);
418 synchronizationGroup->removeVariableId(variableId);
418
419
419 // Removes link between variable and synchronization group
420 // Removes link between variable and synchronization group
420 impl->m_VariableIdGroupIdMap.erase(variableId);
421 impl->m_VariableIdGroupIdMap.erase(variableId);
421 }
422 }
422
423
423 void VariableController::onRequestDataLoading(QVector<std::shared_ptr<Variable> > variables,
424 void VariableController::onRequestDataLoading(QVector<std::shared_ptr<Variable> > variables,
424 const SqpRange &range, const SqpRange &oldRange,
425 const SqpRange &range, const SqpRange &oldRange,
425 bool synchronise)
426 bool synchronise)
426 {
427 {
427 // NOTE: oldRange isn't really necessary since oldRange == variable->range().
428 // NOTE: oldRange isn't really necessary since oldRange == variable->range().
428
429
429 // we want to load data of the variable for the dateTime.
430 // we want to load data of the variable for the dateTime.
430 // First we check if the cache contains some of them.
431 // First we check if the cache contains some of them.
431 // For the other, we ask the provider to give them.
432 // For the other, we ask the provider to give them.
432
433
433 auto varRequestId = QUuid::createUuid();
434 auto varRequestId = QUuid::createUuid();
434 qCInfo(LOG_VariableController()) << "VariableController::onRequestDataLoading"
435 qCDebug(LOG_VariableController()) << "VariableController::onRequestDataLoading"
435 << QThread::currentThread()->objectName() << varRequestId;
436 << QThread::currentThread()->objectName() << varRequestId;
436
437
437 for (const auto &var : variables) {
438 for (const auto &var : variables) {
438 qCDebug(LOG_VariableController()) << "processRequest for" << var->name() << varRequestId;
439 qCDebug(LOG_VariableController()) << "processRequest for" << var->name() << varRequestId;
439 impl->processRequest(var, range, varRequestId);
440 impl->processRequest(var, range, varRequestId);
440 }
441 }
441
442
442 if (synchronise) {
443 if (synchronise) {
443 // Get the group ids
444 // Get the group ids
444 qCDebug(LOG_VariableController())
445 qCDebug(LOG_VariableController())
445 << "TORM VariableController::onRequestDataLoading for synchro var ENABLE";
446 << "TORM VariableController::onRequestDataLoading for synchro var ENABLE";
446 auto groupIds = std::set<QUuid>{};
447 auto groupIds = std::set<QUuid>{};
447 auto groupIdToOldRangeMap = std::map<QUuid, SqpRange>{};
448 auto groupIdToOldRangeMap = std::map<QUuid, SqpRange>{};
448 for (const auto &var : variables) {
449 for (const auto &var : variables) {
449 auto varToVarIdIt = impl->m_VariableToIdentifierMap.find(var);
450 auto varToVarIdIt = impl->m_VariableToIdentifierMap.find(var);
450 if (varToVarIdIt != impl->m_VariableToIdentifierMap.cend()) {
451 if (varToVarIdIt != impl->m_VariableToIdentifierMap.cend()) {
451 auto vId = varToVarIdIt->second;
452 auto vId = varToVarIdIt->second;
452 auto varIdToGroupIdIt = impl->m_VariableIdGroupIdMap.find(vId);
453 auto varIdToGroupIdIt = impl->m_VariableIdGroupIdMap.find(vId);
453 if (varIdToGroupIdIt != impl->m_VariableIdGroupIdMap.cend()) {
454 if (varIdToGroupIdIt != impl->m_VariableIdGroupIdMap.cend()) {
454 auto gId = varIdToGroupIdIt->second;
455 auto gId = varIdToGroupIdIt->second;
455 groupIdToOldRangeMap.insert(std::make_pair(gId, var->range()));
456 groupIdToOldRangeMap.insert(std::make_pair(gId, var->range()));
456 if (groupIds.find(gId) == groupIds.cend()) {
457 if (groupIds.find(gId) == groupIds.cend()) {
457 qCDebug(LOG_VariableController()) << "Synchro detect group " << gId;
458 qCDebug(LOG_VariableController()) << "Synchro detect group " << gId;
458 groupIds.insert(gId);
459 groupIds.insert(gId);
459 }
460 }
460 }
461 }
461 }
462 }
462 }
463 }
463
464
464 // We assume here all group ids exist
465 // We assume here all group ids exist
465 for (const auto &gId : groupIds) {
466 for (const auto &gId : groupIds) {
466 auto vSynchronizationGroup = impl->m_GroupIdToVariableSynchronizationGroupMap.at(gId);
467 auto vSynchronizationGroup = impl->m_GroupIdToVariableSynchronizationGroupMap.at(gId);
467 auto vSyncIds = vSynchronizationGroup->getIds();
468 auto vSyncIds = vSynchronizationGroup->getIds();
468 qCDebug(LOG_VariableController()) << "Var in synchro group ";
469 qCDebug(LOG_VariableController()) << "Var in synchro group ";
469 for (auto vId : vSyncIds) {
470 for (auto vId : vSyncIds) {
470 auto var = impl->findVariable(vId);
471 auto var = impl->findVariable(vId);
471
472
472 // Don't process already processed var
473 // Don't process already processed var
473 if (!variables.contains(var)) {
474 if (!variables.contains(var)) {
474 if (var != nullptr) {
475 if (var != nullptr) {
475 qCDebug(LOG_VariableController())
476 qCDebug(LOG_VariableController())
476 << "processRequest synchro for" << var->name();
477 << "processRequest synchro for" << var->name();
477 auto vSyncRangeRequested = computeSynchroRangeRequested(
478 auto vSyncRangeRequested = computeSynchroRangeRequested(
478 var->range(), range, groupIdToOldRangeMap.at(gId));
479 var->range(), range, groupIdToOldRangeMap.at(gId));
479 qCDebug(LOG_VariableController()) << "synchro RR" << vSyncRangeRequested;
480 qCDebug(LOG_VariableController()) << "synchro RR" << vSyncRangeRequested;
480 impl->processRequest(var, vSyncRangeRequested, varRequestId);
481 impl->processRequest(var, vSyncRangeRequested, varRequestId);
481 }
482 }
482 else {
483 else {
483 qCCritical(LOG_VariableController())
484 qCCritical(LOG_VariableController())
484
485
485 << tr("Impossible to synchronize a null variable");
486 << tr("Impossible to synchronize a null variable");
486 }
487 }
487 }
488 }
488 }
489 }
489 }
490 }
490 }
491 }
491
492
492 impl->updateVariableRequest(varRequestId);
493 impl->updateVariableRequest(varRequestId);
493 }
494 }
494
495
495
496
496 void VariableController::initialize()
497 void VariableController::initialize()
497 {
498 {
498 qCDebug(LOG_VariableController()) << tr("VariableController init") << QThread::currentThread();
499 qCDebug(LOG_VariableController()) << tr("VariableController init") << QThread::currentThread();
499 impl->m_WorkingMutex.lock();
500 impl->m_WorkingMutex.lock();
500 qCDebug(LOG_VariableController()) << tr("VariableController init END");
501 qCDebug(LOG_VariableController()) << tr("VariableController init END");
501 }
502 }
502
503
503 void VariableController::finalize()
504 void VariableController::finalize()
504 {
505 {
505 impl->m_WorkingMutex.unlock();
506 impl->m_WorkingMutex.unlock();
506 }
507 }
507
508
508 void VariableController::waitForFinish()
509 void VariableController::waitForFinish()
509 {
510 {
510 QMutexLocker locker{&impl->m_WorkingMutex};
511 QMutexLocker locker{&impl->m_WorkingMutex};
511 }
512 }
512
513
513 AcquisitionZoomType VariableController::getZoomType(const SqpRange &range, const SqpRange &oldRange)
514 AcquisitionZoomType VariableController::getZoomType(const SqpRange &range, const SqpRange &oldRange)
514 {
515 {
515 // t1.m_TStart <= t2.m_TStart && t2.m_TEnd <= t1.m_TEnd
516 // t1.m_TStart <= t2.m_TStart && t2.m_TEnd <= t1.m_TEnd
516 auto zoomType = AcquisitionZoomType::Unknown;
517 auto zoomType = AcquisitionZoomType::Unknown;
517 if (range.m_TStart <= oldRange.m_TStart && oldRange.m_TEnd <= range.m_TEnd) {
518 if (range.m_TStart <= oldRange.m_TStart && oldRange.m_TEnd <= range.m_TEnd) {
518 zoomType = AcquisitionZoomType::ZoomOut;
519 zoomType = AcquisitionZoomType::ZoomOut;
519 }
520 }
520 else if (range.m_TStart > oldRange.m_TStart && range.m_TEnd > oldRange.m_TEnd) {
521 else if (range.m_TStart > oldRange.m_TStart && range.m_TEnd > oldRange.m_TEnd) {
521 zoomType = AcquisitionZoomType::PanRight;
522 zoomType = AcquisitionZoomType::PanRight;
522 }
523 }
523 else if (range.m_TStart < oldRange.m_TStart && range.m_TEnd < oldRange.m_TEnd) {
524 else if (range.m_TStart < oldRange.m_TStart && range.m_TEnd < oldRange.m_TEnd) {
524 zoomType = AcquisitionZoomType::PanLeft;
525 zoomType = AcquisitionZoomType::PanLeft;
525 }
526 }
526 else if (range.m_TStart > oldRange.m_TStart && oldRange.m_TEnd > range.m_TEnd) {
527 else if (range.m_TStart > oldRange.m_TStart && oldRange.m_TEnd > range.m_TEnd) {
527 zoomType = AcquisitionZoomType::ZoomIn;
528 zoomType = AcquisitionZoomType::ZoomIn;
528 }
529 }
529 else {
530 else {
530 qCCritical(LOG_VariableController()) << "getZoomType: Unknown type detected";
531 qCCritical(LOG_VariableController()) << "getZoomType: Unknown type detected";
531 }
532 }
532 return zoomType;
533 return zoomType;
533 }
534 }
534
535
535 void VariableController::VariableControllerPrivate::processRequest(std::shared_ptr<Variable> var,
536 void VariableController::VariableControllerPrivate::processRequest(std::shared_ptr<Variable> var,
536 const SqpRange &rangeRequested,
537 const SqpRange &rangeRequested,
537 QUuid varRequestId)
538 QUuid varRequestId)
538 {
539 {
539
540
540 // TODO: protect at
541 // TODO: protect at
541 auto varRequest = VariableRequest{};
542 auto varRequest = VariableRequest{};
542 auto varId = m_VariableToIdentifierMap.at(var);
543 auto varId = m_VariableToIdentifierMap.at(var);
543
544
544 auto varStrategyRangesRequested
545 auto varStrategyRangesRequested
545 = m_VariableCacheStrategy->computeStrategyRanges(var->range(), rangeRequested);
546 = m_VariableCacheStrategy->computeStrategyRanges(var->range(), rangeRequested);
546 auto notInCacheRangeList = var->provideNotInCacheRangeList(varStrategyRangesRequested.second);
547 auto notInCacheRangeList = var->provideNotInCacheRangeList(varStrategyRangesRequested.second);
547 auto inCacheRangeList = var->provideInCacheRangeList(varStrategyRangesRequested.second);
548 auto inCacheRangeList = var->provideInCacheRangeList(varStrategyRangesRequested.second);
548
549
549 if (!notInCacheRangeList.empty()) {
550 if (!notInCacheRangeList.empty()) {
550 varRequest.m_RangeRequested = varStrategyRangesRequested.first;
551 varRequest.m_RangeRequested = varStrategyRangesRequested.first;
551 varRequest.m_CacheRangeRequested = varStrategyRangesRequested.second;
552 varRequest.m_CacheRangeRequested = varStrategyRangesRequested.second;
552 qCDebug(LOG_VariableAcquisitionWorker()) << tr("TORM processRequest RR ") << rangeRequested;
553 qCInfo(LOG_VariableController()) << tr("TORM processRequest RR ") << rangeRequested;
553 qCDebug(LOG_VariableAcquisitionWorker())
554 qCInfo(LOG_VariableController())
554 << tr("TORM processRequest R ") << varStrategyRangesRequested.first;
555 << tr("TORM processRequest R ") << varStrategyRangesRequested.first;
555 qCDebug(LOG_VariableAcquisitionWorker())
556 qCInfo(LOG_VariableController())
556 << tr("TORM processRequest CR ") << varStrategyRangesRequested.second;
557 << tr("TORM processRequest CR ") << varStrategyRangesRequested.second;
557 // store VarRequest
558 // store VarRequest
558 storeVariableRequest(varId, varRequestId, varRequest);
559 storeVariableRequest(varId, varRequestId, varRequest);
559
560
560 auto varProvider = m_VariableToProviderMap.at(var);
561 auto varProvider = m_VariableToProviderMap.at(var);
561 if (varProvider != nullptr) {
562 if (varProvider != nullptr) {
562 auto varRequestIdCanceled = m_VariableAcquisitionWorker->pushVariableRequest(
563 auto varRequestIdCanceled = m_VariableAcquisitionWorker->pushVariableRequest(
563 varRequestId, varId, varStrategyRangesRequested.first,
564 varRequestId, varId, varStrategyRangesRequested.first,
564 varStrategyRangesRequested.second,
565 varStrategyRangesRequested.second,
565 DataProviderParameters{std::move(notInCacheRangeList), var->metadata()},
566 DataProviderParameters{std::move(notInCacheRangeList), var->metadata()},
566 varProvider);
567 varProvider);
567
568
568 if (!varRequestIdCanceled.isNull()) {
569 if (!varRequestIdCanceled.isNull()) {
569 qCInfo(LOG_VariableAcquisitionWorker())
570 qCInfo(LOG_VariableController())
570 << tr("varRequestIdCanceled: ") << varRequestIdCanceled;
571 << tr("varRequestIdCanceled: ") << varRequestIdCanceled;
571 cancelVariableRequest(varRequestIdCanceled);
572 cancelVariableRequest(varRequestIdCanceled);
572 }
573 }
573 }
574 }
574 else {
575 else {
575 qCCritical(LOG_VariableController())
576 qCCritical(LOG_VariableController())
576 << "Impossible to provide data with a null provider";
577 << "Impossible to provide data with a null provider";
577 }
578 }
578
579
579 if (!inCacheRangeList.empty()) {
580 if (!inCacheRangeList.empty()) {
580 emit q->updateVarDisplaying(var, inCacheRangeList.first());
581 emit q->updateVarDisplaying(var, inCacheRangeList.first());
581 }
582 }
582 }
583 }
583 else {
584 else {
584
585
585 varRequest.m_RangeRequested = varStrategyRangesRequested.first;
586 varRequest.m_RangeRequested = varStrategyRangesRequested.first;
586 varRequest.m_CacheRangeRequested = varStrategyRangesRequested.second;
587 varRequest.m_CacheRangeRequested = varStrategyRangesRequested.second;
587 // store VarRequest
588 // store VarRequest
588 storeVariableRequest(varId, varRequestId, varRequest);
589 storeVariableRequest(varId, varRequestId, varRequest);
589 acceptVariableRequest(varId,
590 acceptVariableRequest(varId,
590 var->dataSeries()->subDataSeries(varStrategyRangesRequested.second));
591 var->dataSeries()->subDataSeries(varStrategyRangesRequested.second));
591 }
592 }
592 }
593 }
593
594
594 std::shared_ptr<Variable>
595 std::shared_ptr<Variable>
595 VariableController::VariableControllerPrivate::findVariable(QUuid vIdentifier)
596 VariableController::VariableControllerPrivate::findVariable(QUuid vIdentifier)
596 {
597 {
597 std::shared_ptr<Variable> var;
598 std::shared_ptr<Variable> var;
598 auto findReply = [vIdentifier](const auto &entry) { return vIdentifier == entry.second; };
599 auto findReply = [vIdentifier](const auto &entry) { return vIdentifier == entry.second; };
599
600
600 auto end = m_VariableToIdentifierMap.cend();
601 auto end = m_VariableToIdentifierMap.cend();
601 auto it = std::find_if(m_VariableToIdentifierMap.cbegin(), end, findReply);
602 auto it = std::find_if(m_VariableToIdentifierMap.cbegin(), end, findReply);
602 if (it != end) {
603 if (it != end) {
603 var = it->first;
604 var = it->first;
604 }
605 }
605 else {
606 else {
606 qCCritical(LOG_VariableController())
607 qCCritical(LOG_VariableController())
607 << tr("Impossible to find the variable with the identifier: ") << vIdentifier;
608 << tr("Impossible to find the variable with the identifier: ") << vIdentifier;
608 }
609 }
609
610
610 return var;
611 return var;
611 }
612 }
612
613
613 std::shared_ptr<IDataSeries> VariableController::VariableControllerPrivate::retrieveDataSeries(
614 std::shared_ptr<IDataSeries> VariableController::VariableControllerPrivate::retrieveDataSeries(
614 const QVector<AcquisitionDataPacket> acqDataPacketVector)
615 const QVector<AcquisitionDataPacket> acqDataPacketVector)
615 {
616 {
616 qCDebug(LOG_VariableController())
617 qCDebug(LOG_VariableController())
617 << tr("TORM: retrieveDataSeries acqDataPacketVector size") << acqDataPacketVector.size();
618 << tr("TORM: retrieveDataSeries acqDataPacketVector size") << acqDataPacketVector.size();
618 std::shared_ptr<IDataSeries> dataSeries;
619 std::shared_ptr<IDataSeries> dataSeries;
619 if (!acqDataPacketVector.isEmpty()) {
620 if (!acqDataPacketVector.isEmpty()) {
620 dataSeries = acqDataPacketVector[0].m_DateSeries;
621 dataSeries = acqDataPacketVector[0].m_DateSeries;
621 for (int i = 1; i < acqDataPacketVector.size(); ++i) {
622 for (int i = 1; i < acqDataPacketVector.size(); ++i) {
622 dataSeries->merge(acqDataPacketVector[i].m_DateSeries.get());
623 dataSeries->merge(acqDataPacketVector[i].m_DateSeries.get());
623 }
624 }
624 }
625 }
625 qCDebug(LOG_VariableController()) << tr("TORM: retrieveDataSeries acqDataPacketVector size END")
626 qCDebug(LOG_VariableController()) << tr("TORM: retrieveDataSeries acqDataPacketVector size END")
626 << acqDataPacketVector.size();
627 << acqDataPacketVector.size();
627 return dataSeries;
628 return dataSeries;
628 }
629 }
629
630
630 void VariableController::VariableControllerPrivate::registerProvider(
631 void VariableController::VariableControllerPrivate::registerProvider(
631 std::shared_ptr<IDataProvider> provider)
632 std::shared_ptr<IDataProvider> provider)
632 {
633 {
633 if (m_ProviderSet.find(provider) == m_ProviderSet.end()) {
634 if (m_ProviderSet.find(provider) == m_ProviderSet.end()) {
634 qCDebug(LOG_VariableController())
635 qCDebug(LOG_VariableController())
635 << tr("Registering of a new provider") << provider->objectName();
636 << tr("Registering of a new provider") << provider->objectName();
636 m_ProviderSet.insert(provider);
637 m_ProviderSet.insert(provider);
637 connect(provider.get(), &IDataProvider::dataProvided, m_VariableAcquisitionWorker.get(),
638 connect(provider.get(), &IDataProvider::dataProvided, m_VariableAcquisitionWorker.get(),
638 &VariableAcquisitionWorker::onVariableDataAcquired);
639 &VariableAcquisitionWorker::onVariableDataAcquired);
639 connect(provider.get(), &IDataProvider::dataProvidedProgress,
640 connect(provider.get(), &IDataProvider::dataProvidedProgress,
640 m_VariableAcquisitionWorker.get(),
641 m_VariableAcquisitionWorker.get(),
641 &VariableAcquisitionWorker::onVariableRetrieveDataInProgress);
642 &VariableAcquisitionWorker::onVariableRetrieveDataInProgress);
642 }
643 }
643 else {
644 else {
644 qCDebug(LOG_VariableController()) << tr("Cannot register provider, it already exists ");
645 qCDebug(LOG_VariableController()) << tr("Cannot register provider, it already exists ");
645 }
646 }
646 }
647 }
647
648
648 void VariableController::VariableControllerPrivate::storeVariableRequest(
649 void VariableController::VariableControllerPrivate::storeVariableRequest(
649 QUuid varId, QUuid varRequestId, const VariableRequest &varRequest)
650 QUuid varId, QUuid varRequestId, const VariableRequest &varRequest)
650 {
651 {
651 // First request for the variable. we can create an entry for it
652 // First request for the variable. we can create an entry for it
652 auto varIdToVarRequestIdQueueMapIt = m_VarIdToVarRequestIdQueueMap.find(varId);
653 auto varIdToVarRequestIdQueueMapIt = m_VarIdToVarRequestIdQueueMap.find(varId);
653 if (varIdToVarRequestIdQueueMapIt == m_VarIdToVarRequestIdQueueMap.cend()) {
654 if (varIdToVarRequestIdQueueMapIt == m_VarIdToVarRequestIdQueueMap.cend()) {
654 auto varRequestIdQueue = std::deque<QUuid>{};
655 auto varRequestIdQueue = std::deque<QUuid>{};
655 qCDebug(LOG_VariableController()) << tr("Store REQUEST in QUEUE");
656 qCInfo(LOG_VariableController()) << tr("Store REQUEST in QUEUE");
656 varRequestIdQueue.push_back(varRequestId);
657 varRequestIdQueue.push_back(varRequestId);
657 m_VarIdToVarRequestIdQueueMap.insert(std::make_pair(varId, std::move(varRequestIdQueue)));
658 m_VarIdToVarRequestIdQueueMap.insert(std::make_pair(varId, std::move(varRequestIdQueue)));
658 }
659 }
659 else {
660 else {
660 qCDebug(LOG_VariableController()) << tr("Store REQUEST in EXISTING QUEUE");
661 qCInfo(LOG_VariableController()) << tr("Store REQUEST in EXISTING QUEUE");
661 auto &varRequestIdQueue = varIdToVarRequestIdQueueMapIt->second;
662 auto &varRequestIdQueue = varIdToVarRequestIdQueueMapIt->second;
662 varRequestIdQueue.push_back(varRequestId);
663 varRequestIdQueue.push_back(varRequestId);
663 }
664 }
664
665
665 auto varRequestIdToVarIdVarRequestMapIt = m_VarRequestIdToVarIdVarRequestMap.find(varRequestId);
666 auto varRequestIdToVarIdVarRequestMapIt = m_VarRequestIdToVarIdVarRequestMap.find(varRequestId);
666 if (varRequestIdToVarIdVarRequestMapIt == m_VarRequestIdToVarIdVarRequestMap.cend()) {
667 if (varRequestIdToVarIdVarRequestMapIt == m_VarRequestIdToVarIdVarRequestMap.cend()) {
667 auto varIdToVarRequestMap = std::map<QUuid, VariableRequest>{};
668 auto varIdToVarRequestMap = std::map<QUuid, VariableRequest>{};
668 varIdToVarRequestMap.insert(std::make_pair(varId, varRequest));
669 varIdToVarRequestMap.insert(std::make_pair(varId, varRequest));
669 qCDebug(LOG_VariableController()) << tr("Store REQUESTID in MAP");
670 qCInfo(LOG_VariableController()) << tr("Store REQUESTID in MAP");
670 m_VarRequestIdToVarIdVarRequestMap.insert(
671 m_VarRequestIdToVarIdVarRequestMap.insert(
671 std::make_pair(varRequestId, std::move(varIdToVarRequestMap)));
672 std::make_pair(varRequestId, std::move(varIdToVarRequestMap)));
672 }
673 }
673 else {
674 else {
674 auto &varIdToVarRequestMap = varRequestIdToVarIdVarRequestMapIt->second;
675 auto &varIdToVarRequestMap = varRequestIdToVarIdVarRequestMapIt->second;
675 qCDebug(LOG_VariableController()) << tr("Store REQUESTID in EXISTING MAP");
676 qCInfo(LOG_VariableController()) << tr("Store REQUESTID in EXISTING MAP");
676 varIdToVarRequestMap.insert(std::make_pair(varId, varRequest));
677 varIdToVarRequestMap.insert(std::make_pair(varId, varRequest));
677 }
678 }
678 }
679 }
679
680
680 QUuid VariableController::VariableControllerPrivate::acceptVariableRequest(
681 QUuid VariableController::VariableControllerPrivate::acceptVariableRequest(
681 QUuid varId, std::shared_ptr<IDataSeries> dataSeries)
682 QUuid varId, std::shared_ptr<IDataSeries> dataSeries)
682 {
683 {
683 QUuid varRequestId;
684 QUuid varRequestId;
684 auto varIdToVarRequestIdQueueMapIt = m_VarIdToVarRequestIdQueueMap.find(varId);
685 auto varIdToVarRequestIdQueueMapIt = m_VarIdToVarRequestIdQueueMap.find(varId);
685 if (varIdToVarRequestIdQueueMapIt != m_VarIdToVarRequestIdQueueMap.cend()) {
686 if (varIdToVarRequestIdQueueMapIt != m_VarIdToVarRequestIdQueueMap.cend()) {
686 auto &varRequestIdQueue = varIdToVarRequestIdQueueMapIt->second;
687 auto &varRequestIdQueue = varIdToVarRequestIdQueueMapIt->second;
687 varRequestId = varRequestIdQueue.front();
688 varRequestId = varRequestIdQueue.front();
688 auto varRequestIdToVarIdVarRequestMapIt
689 auto varRequestIdToVarIdVarRequestMapIt
689 = m_VarRequestIdToVarIdVarRequestMap.find(varRequestId);
690 = m_VarRequestIdToVarIdVarRequestMap.find(varRequestId);
690 if (varRequestIdToVarIdVarRequestMapIt != m_VarRequestIdToVarIdVarRequestMap.cend()) {
691 if (varRequestIdToVarIdVarRequestMapIt != m_VarRequestIdToVarIdVarRequestMap.cend()) {
691 auto &varIdToVarRequestMap = varRequestIdToVarIdVarRequestMapIt->second;
692 auto &varIdToVarRequestMap = varRequestIdToVarIdVarRequestMapIt->second;
692 auto varIdToVarRequestMapIt = varIdToVarRequestMap.find(varId);
693 auto varIdToVarRequestMapIt = varIdToVarRequestMap.find(varId);
693 if (varIdToVarRequestMapIt != varIdToVarRequestMap.cend()) {
694 if (varIdToVarRequestMapIt != varIdToVarRequestMap.cend()) {
694 qCDebug(LOG_VariableController()) << tr("acceptVariableRequest");
695 qCDebug(LOG_VariableController()) << tr("acceptVariableRequest");
695 auto &varRequest = varIdToVarRequestMapIt->second;
696 auto &varRequest = varIdToVarRequestMapIt->second;
696 varRequest.m_DataSeries = dataSeries;
697 varRequest.m_DataSeries = dataSeries;
697 varRequest.m_CanUpdate = true;
698 varRequest.m_CanUpdate = true;
698 }
699 }
699 else {
700 else {
700 qCDebug(LOG_VariableController())
701 qCDebug(LOG_VariableController())
701 << tr("Impossible to acceptVariableRequest of a unknown variable id attached "
702 << tr("Impossible to acceptVariableRequest of a unknown variable id attached "
702 "to a variableRequestId")
703 "to a variableRequestId")
703 << varRequestId << varId;
704 << varRequestId << varId;
704 }
705 }
705 }
706 }
706 else {
707 else {
707 qCCritical(LOG_VariableController())
708 qCCritical(LOG_VariableController())
708 << tr("Impossible to acceptVariableRequest of a unknown variableRequestId")
709 << tr("Impossible to acceptVariableRequest of a unknown variableRequestId")
709 << varRequestId;
710 << varRequestId;
710 }
711 }
711
712
712 qCDebug(LOG_VariableController())
713 qCDebug(LOG_VariableController())
713 << tr("1: erase REQUEST in QUEUE ?") << varRequestIdQueue.size();
714 << tr("1: erase REQUEST in QUEUE ?") << varRequestIdQueue.size();
714 varRequestIdQueue.pop_front();
715 varRequestIdQueue.pop_front();
715 qCDebug(LOG_VariableController())
716 qCDebug(LOG_VariableController())
716 << tr("2: erase REQUEST in QUEUE ?") << varRequestIdQueue.size();
717 << tr("2: erase REQUEST in QUEUE ?") << varRequestIdQueue.size();
717 if (varRequestIdQueue.empty()) {
718 if (varRequestIdQueue.empty()) {
718 m_VarIdToVarRequestIdQueueMap.erase(varId);
719 m_VarIdToVarRequestIdQueueMap.erase(varId);
719 }
720 }
720 }
721 }
721 else {
722 else {
722 qCCritical(LOG_VariableController())
723 qCCritical(LOG_VariableController())
723 << tr("Impossible to acceptVariableRequest of a unknown variable id") << varId;
724 << tr("Impossible to acceptVariableRequest of a unknown variable id") << varId;
724 }
725 }
725
726
726 return varRequestId;
727 return varRequestId;
727 }
728 }
728
729
729 void VariableController::VariableControllerPrivate::updateVariableRequest(QUuid varRequestId)
730 void VariableController::VariableControllerPrivate::updateVariableRequest(QUuid varRequestId)
730 {
731 {
731
732
732 auto varRequestIdToVarIdVarRequestMapIt = m_VarRequestIdToVarIdVarRequestMap.find(varRequestId);
733 auto varRequestIdToVarIdVarRequestMapIt = m_VarRequestIdToVarIdVarRequestMap.find(varRequestId);
733 if (varRequestIdToVarIdVarRequestMapIt != m_VarRequestIdToVarIdVarRequestMap.cend()) {
734 if (varRequestIdToVarIdVarRequestMapIt != m_VarRequestIdToVarIdVarRequestMap.cend()) {
734 bool processVariableUpdate = true;
735 bool processVariableUpdate = true;
735 auto &varIdToVarRequestMap = varRequestIdToVarIdVarRequestMapIt->second;
736 auto &varIdToVarRequestMap = varRequestIdToVarIdVarRequestMapIt->second;
736 for (auto varIdToVarRequestMapIt = varIdToVarRequestMap.cbegin();
737 for (auto varIdToVarRequestMapIt = varIdToVarRequestMap.cbegin();
737 (varIdToVarRequestMapIt != varIdToVarRequestMap.cend()) && processVariableUpdate;
738 (varIdToVarRequestMapIt != varIdToVarRequestMap.cend()) && processVariableUpdate;
738 ++varIdToVarRequestMapIt) {
739 ++varIdToVarRequestMapIt) {
739 processVariableUpdate &= varIdToVarRequestMapIt->second.m_CanUpdate;
740 processVariableUpdate &= varIdToVarRequestMapIt->second.m_CanUpdate;
740 qCDebug(LOG_VariableController())
741 qCDebug(LOG_VariableController())
741 << tr("updateVariableRequest") << processVariableUpdate;
742 << tr("updateVariableRequest") << processVariableUpdate;
742 }
743 }
743
744
744 if (processVariableUpdate) {
745 if (processVariableUpdate) {
745 for (auto varIdToVarRequestMapIt = varIdToVarRequestMap.cbegin();
746 for (auto varIdToVarRequestMapIt = varIdToVarRequestMap.cbegin();
746 varIdToVarRequestMapIt != varIdToVarRequestMap.cend(); ++varIdToVarRequestMapIt) {
747 varIdToVarRequestMapIt != varIdToVarRequestMap.cend(); ++varIdToVarRequestMapIt) {
747 if (auto var = findVariable(varIdToVarRequestMapIt->first)) {
748 if (auto var = findVariable(varIdToVarRequestMapIt->first)) {
748 auto &varRequest = varIdToVarRequestMapIt->second;
749 auto &varRequest = varIdToVarRequestMapIt->second;
749 var->setRange(varRequest.m_RangeRequested);
750 var->setRange(varRequest.m_RangeRequested);
750 var->setCacheRange(varRequest.m_CacheRangeRequested);
751 var->setCacheRange(varRequest.m_CacheRangeRequested);
751 qCDebug(LOG_VariableController())
752 qCDebug(LOG_VariableController())
752 << tr("1: onDataProvided") << varRequest.m_RangeRequested;
753 << tr("1: onDataProvided") << varRequest.m_RangeRequested;
753 qCDebug(LOG_VariableController())
754 qCDebug(LOG_VariableController())
754 << tr("2: onDataProvided") << varRequest.m_CacheRangeRequested;
755 << tr("2: onDataProvided") << varRequest.m_CacheRangeRequested;
755 var->mergeDataSeries(varRequest.m_DataSeries);
756 var->mergeDataSeries(varRequest.m_DataSeries);
756 qCDebug(LOG_VariableController())
757 qCDebug(LOG_VariableController())
757 << tr("3: onDataProvided") << varRequest.m_DataSeries->range();
758 << tr("3: onDataProvided") << varRequest.m_DataSeries->range();
758 qCDebug(LOG_VariableController()) << tr("4: onDataProvided");
759 qCDebug(LOG_VariableController()) << tr("4: onDataProvided");
759
760
760 /// @todo MPL: confirm
761 /// @todo MPL: confirm
761 // Variable update is notified only if there is no pending request for it
762 // Variable update is notified only if there is no pending request for it
762 if (m_VarIdToVarRequestIdQueueMap.count(varIdToVarRequestMapIt->first) == 0) {
763 if (m_VarIdToVarRequestIdQueueMap.count(varIdToVarRequestMapIt->first) == 0) {
763 emit var->updated();
764 emit var->updated();
764 }
765 }
765 }
766 }
766 else {
767 else {
767 qCCritical(LOG_VariableController())
768 qCCritical(LOG_VariableController())
768 << tr("Impossible to update data to a null variable");
769 << tr("Impossible to update data to a null variable");
769 }
770 }
770 }
771 }
771
772
772 // cleaning varRequestId
773 // cleaning varRequestId
773 qCDebug(LOG_VariableController())
774 qCDebug(LOG_VariableController())
774 << tr("0: erase REQUEST in MAP ?") << m_VarRequestIdToVarIdVarRequestMap.size();
775 << tr("0: erase REQUEST in MAP ?") << m_VarRequestIdToVarIdVarRequestMap.size();
775 m_VarRequestIdToVarIdVarRequestMap.erase(varRequestId);
776 m_VarRequestIdToVarIdVarRequestMap.erase(varRequestId);
776 qCDebug(LOG_VariableController())
777 qCDebug(LOG_VariableController())
777 << tr("1: erase REQUEST in MAP ?") << m_VarRequestIdToVarIdVarRequestMap.size();
778 << tr("1: erase REQUEST in MAP ?") << m_VarRequestIdToVarIdVarRequestMap.size();
778 }
779 }
779 }
780 }
780 else {
781 else {
781 qCCritical(LOG_VariableController())
782 qCCritical(LOG_VariableController())
782 << tr("Cannot updateVariableRequest for a unknow varRequestId") << varRequestId;
783 << tr("Cannot updateVariableRequest for a unknow varRequestId") << varRequestId;
783 }
784 }
784 }
785 }
785
786
786 void VariableController::VariableControllerPrivate::cancelVariableRequest(QUuid varRequestId)
787 void VariableController::VariableControllerPrivate::cancelVariableRequest(QUuid varRequestId)
787 {
788 {
788 // cleaning varRequestId
789 // cleaning varRequestId
789 m_VarRequestIdToVarIdVarRequestMap.erase(varRequestId);
790 m_VarRequestIdToVarIdVarRequestMap.erase(varRequestId);
790
791
791 for (auto varIdToVarRequestIdQueueMapIt = m_VarIdToVarRequestIdQueueMap.begin();
792 for (auto varIdToVarRequestIdQueueMapIt = m_VarIdToVarRequestIdQueueMap.begin();
792 varIdToVarRequestIdQueueMapIt != m_VarIdToVarRequestIdQueueMap.end();) {
793 varIdToVarRequestIdQueueMapIt != m_VarIdToVarRequestIdQueueMap.end();) {
793 auto &varRequestIdQueue = varIdToVarRequestIdQueueMapIt->second;
794 auto &varRequestIdQueue = varIdToVarRequestIdQueueMapIt->second;
794 varRequestIdQueue.erase(
795 varRequestIdQueue.erase(
795 std::remove(varRequestIdQueue.begin(), varRequestIdQueue.end(), varRequestId),
796 std::remove(varRequestIdQueue.begin(), varRequestIdQueue.end(), varRequestId),
796 varRequestIdQueue.end());
797 varRequestIdQueue.end());
797 if (varRequestIdQueue.empty()) {
798 if (varRequestIdQueue.empty()) {
798 varIdToVarRequestIdQueueMapIt
799 varIdToVarRequestIdQueueMapIt
799 = m_VarIdToVarRequestIdQueueMap.erase(varIdToVarRequestIdQueueMapIt);
800 = m_VarIdToVarRequestIdQueueMap.erase(varIdToVarRequestIdQueueMapIt);
800 }
801 }
801 else {
802 else {
802 ++varIdToVarRequestIdQueueMapIt;
803 ++varIdToVarRequestIdQueueMapIt;
803 }
804 }
804 }
805 }
805 }
806 }
@@ -1,174 +1,184
1 #include "AmdaProvider.h"
1 #include "AmdaProvider.h"
2 #include "AmdaDefs.h"
2 #include "AmdaDefs.h"
3 #include "AmdaResultParser.h"
3 #include "AmdaResultParser.h"
4
4
5 #include <Common/DateUtils.h>
5 #include <Common/DateUtils.h>
6 #include <Data/DataProviderParameters.h>
6 #include <Data/DataProviderParameters.h>
7 #include <Network/NetworkController.h>
7 #include <Network/NetworkController.h>
8 #include <SqpApplication.h>
8 #include <SqpApplication.h>
9 #include <Variable/Variable.h>
9 #include <Variable/Variable.h>
10
10
11 #include <QNetworkAccessManager>
11 #include <QNetworkAccessManager>
12 #include <QNetworkReply>
12 #include <QNetworkReply>
13 #include <QTemporaryFile>
13 #include <QTemporaryFile>
14 #include <QThread>
14 #include <QThread>
15
15
16 #include <QElapsedTimer>
17
16 Q_LOGGING_CATEGORY(LOG_AmdaProvider, "AmdaProvider")
18 Q_LOGGING_CATEGORY(LOG_AmdaProvider, "AmdaProvider")
17
19
18 namespace {
20 namespace {
19
21
20 /// URL format for a request on AMDA server. The parameters are as follows:
22 /// URL format for a request on AMDA server. The parameters are as follows:
21 /// - %1: start date
23 /// - %1: start date
22 /// - %2: end date
24 /// - %2: end date
23 /// - %3: parameter id
25 /// - %3: parameter id
24 const auto AMDA_URL_FORMAT = QStringLiteral(
26 const auto AMDA_URL_FORMAT = QStringLiteral(
25 "http://amda.irap.omp.eu/php/rest/"
27 "http://amda.irap.omp.eu/php/rest/"
26 "getParameter.php?startTime=%1&stopTime=%2&parameterID=%3&outputFormat=ASCII&"
28 "getParameter.php?startTime=%1&stopTime=%2&parameterID=%3&outputFormat=ASCII&"
27 "timeFormat=ISO8601&gzip=0");
29 "timeFormat=ISO8601&gzip=0");
28
30
29 /// Dates format passed in the URL (e.g 2013-09-23T09:00)
31 /// Dates format passed in the URL (e.g 2013-09-23T09:00)
30 const auto AMDA_TIME_FORMAT = QStringLiteral("yyyy-MM-ddThh:mm:ss");
32 const auto AMDA_TIME_FORMAT = QStringLiteral("yyyy-MM-ddThh:mm:ss");
31
33
32 /// Formats a time to a date that can be passed in URL
34 /// Formats a time to a date that can be passed in URL
33 QString dateFormat(double sqpRange) noexcept
35 QString dateFormat(double sqpRange) noexcept
34 {
36 {
35 auto dateTime = DateUtils::dateTime(sqpRange);
37 auto dateTime = DateUtils::dateTime(sqpRange);
36 return dateTime.toString(AMDA_TIME_FORMAT);
38 return dateTime.toString(AMDA_TIME_FORMAT);
37 }
39 }
38
40
39 AmdaResultParser::ValueType valueType(const QString &valueType)
41 AmdaResultParser::ValueType valueType(const QString &valueType)
40 {
42 {
41 if (valueType == QStringLiteral("scalar")) {
43 if (valueType == QStringLiteral("scalar")) {
42 return AmdaResultParser::ValueType::SCALAR;
44 return AmdaResultParser::ValueType::SCALAR;
43 }
45 }
44 else if (valueType == QStringLiteral("vector")) {
46 else if (valueType == QStringLiteral("vector")) {
45 return AmdaResultParser::ValueType::VECTOR;
47 return AmdaResultParser::ValueType::VECTOR;
46 }
48 }
47 else {
49 else {
48 return AmdaResultParser::ValueType::UNKNOWN;
50 return AmdaResultParser::ValueType::UNKNOWN;
49 }
51 }
50 }
52 }
51
53
52 } // namespace
54 } // namespace
53
55
54 AmdaProvider::AmdaProvider()
56 AmdaProvider::AmdaProvider()
55 {
57 {
56 qCDebug(LOG_AmdaProvider()) << tr("AmdaProvider::AmdaProvider") << QThread::currentThread();
58 qCDebug(LOG_AmdaProvider()) << tr("AmdaProvider::AmdaProvider") << QThread::currentThread();
57 if (auto app = sqpApp) {
59 if (auto app = sqpApp) {
58 auto &networkController = app->networkController();
60 auto &networkController = app->networkController();
59 connect(this, SIGNAL(requestConstructed(QNetworkRequest, QUuid,
61 connect(this, SIGNAL(requestConstructed(QNetworkRequest, QUuid,
60 std::function<void(QNetworkReply *, QUuid)>)),
62 std::function<void(QNetworkReply *, QUuid)>)),
61 &networkController,
63 &networkController,
62 SLOT(onProcessRequested(QNetworkRequest, QUuid,
64 SLOT(onProcessRequested(QNetworkRequest, QUuid,
63 std::function<void(QNetworkReply *, QUuid)>)));
65 std::function<void(QNetworkReply *, QUuid)>)));
64
66
65
67
66 connect(&sqpApp->networkController(), SIGNAL(replyDownloadProgress(QUuid, double)), this,
68 connect(&sqpApp->networkController(), SIGNAL(replyDownloadProgress(QUuid, double)), this,
67 SIGNAL(dataProvidedProgress(QUuid, double)));
69 SIGNAL(dataProvidedProgress(QUuid, double)));
68 }
70 }
69 }
71 }
70
72
71 std::shared_ptr<IDataProvider> AmdaProvider::clone() const
73 std::shared_ptr<IDataProvider> AmdaProvider::clone() const
72 {
74 {
73 // No copy is made in the clone
75 // No copy is made in the clone
74 return std::make_shared<AmdaProvider>();
76 return std::make_shared<AmdaProvider>();
75 }
77 }
76
78
77 void AmdaProvider::requestDataLoading(QUuid acqIdentifier, const DataProviderParameters &parameters)
79 void AmdaProvider::requestDataLoading(QUuid acqIdentifier, const DataProviderParameters &parameters)
78 {
80 {
79 // NOTE: Try to use multithread if possible
81 // NOTE: Try to use multithread if possible
80 const auto times = parameters.m_Times;
82 const auto times = parameters.m_Times;
81 const auto data = parameters.m_Data;
83 const auto data = parameters.m_Data;
82 for (const auto &dateTime : qAsConst(times)) {
84 for (const auto &dateTime : qAsConst(times)) {
83 this->retrieveData(acqIdentifier, dateTime, data);
85 this->retrieveData(acqIdentifier, dateTime, data);
84
86
85 // TORM when AMDA will support quick asynchrone request
87 // TORM when AMDA will support quick asynchrone request
86 QThread::msleep(1000);
88 QThread::msleep(1000);
87 }
89 }
88 }
90 }
89
91
90 void AmdaProvider::requestDataAborting(QUuid acqIdentifier)
92 void AmdaProvider::requestDataAborting(QUuid acqIdentifier)
91 {
93 {
92 if (auto app = sqpApp) {
94 if (auto app = sqpApp) {
93 auto &networkController = app->networkController();
95 auto &networkController = app->networkController();
94 networkController.onReplyCanceled(acqIdentifier);
96 networkController.onReplyCanceled(acqIdentifier);
95 }
97 }
96 }
98 }
97
99
98 void AmdaProvider::retrieveData(QUuid token, const SqpRange &dateTime, const QVariantHash &data)
100 void AmdaProvider::retrieveData(QUuid token, const SqpRange &dateTime, const QVariantHash &data)
99 {
101 {
100 // Retrieves product ID from data: if the value is invalid, no request is made
102 // Retrieves product ID from data: if the value is invalid, no request is made
101 auto productId = data.value(AMDA_XML_ID_KEY).toString();
103 auto productId = data.value(AMDA_XML_ID_KEY).toString();
102 if (productId.isNull()) {
104 if (productId.isNull()) {
103 qCCritical(LOG_AmdaProvider()) << tr("Can't retrieve data: unknown product id");
105 qCCritical(LOG_AmdaProvider()) << tr("Can't retrieve data: unknown product id");
104 return;
106 return;
105 }
107 }
106 qCDebug(LOG_AmdaProvider()) << tr("AmdaProvider::retrieveData") << dateTime;
108 qCDebug(LOG_AmdaProvider()) << tr("AmdaProvider::retrieveData") << dateTime;
107
109
108 // Retrieves the data type that determines whether the expected format for the result file is
110 // Retrieves the data type that determines whether the expected format for the result file is
109 // scalar, vector...
111 // scalar, vector...
110 auto productValueType = valueType(data.value(AMDA_DATA_TYPE_KEY).toString());
112 auto productValueType = valueType(data.value(AMDA_DATA_TYPE_KEY).toString());
111
113
112 // /////////// //
114 // /////////// //
113 // Creates URL //
115 // Creates URL //
114 // /////////// //
116 // /////////// //
115
117
116 auto startDate = dateFormat(dateTime.m_TStart);
118 auto startDate = dateFormat(dateTime.m_TStart);
117 auto endDate = dateFormat(dateTime.m_TEnd);
119 auto endDate = dateFormat(dateTime.m_TEnd);
118
120
119 auto url = QUrl{QString{AMDA_URL_FORMAT}.arg(startDate, endDate, productId)};
121 auto url = QUrl{QString{AMDA_URL_FORMAT}.arg(startDate, endDate, productId)};
120 qCInfo(LOG_AmdaProvider()) << tr("TORM AmdaProvider::retrieveData url:") << url;
122 qCInfo(LOG_AmdaProvider()) << token << tr("AmdaProvider::retrieveData url:") << url;
121 auto tempFile = std::make_shared<QTemporaryFile>();
123 auto tempFile = std::make_shared<QTemporaryFile>();
122
124
123 // LAMBDA
125 // LAMBDA
124 auto httpDownloadFinished = [this, dateTime, tempFile,
126 auto httpDownloadFinished = [this, dateTime, tempFile,
125 productValueType](QNetworkReply *reply, QUuid dataId) noexcept {
127 productValueType](QNetworkReply *reply, QUuid dataId) noexcept {
126
128
129 qCInfo(LOG_AmdaProvider()) << "Download url file completed" << dataId;
130
127 // Don't do anything if the reply was abort
131 // Don't do anything if the reply was abort
128 if (reply->error() != QNetworkReply::OperationCanceledError) {
132 if (reply->error() != QNetworkReply::OperationCanceledError) {
129
133 QElapsedTimer timer{};
134 timer.start();
130 if (tempFile) {
135 if (tempFile) {
131 auto replyReadAll = reply->readAll();
136 auto replyReadAll = reply->readAll();
132 if (!replyReadAll.isEmpty()) {
137 if (!replyReadAll.isEmpty()) {
133 tempFile->write(replyReadAll);
138 tempFile->write(replyReadAll);
134 }
139 }
135 tempFile->close();
140 tempFile->close();
136
141
137 // Parse results file
142 // Parse results file
138 if (auto dataSeries
143 if (auto dataSeries
139 = AmdaResultParser::readTxt(tempFile->fileName(), productValueType)) {
144 = AmdaResultParser::readTxt(tempFile->fileName(), productValueType)) {
145 qCInfo(LOG_AmdaProvider()) << tr("Request was finished") << dataId << "(took"
146 << timer.elapsed() << "ms)";
140 emit dataProvided(dataId, dataSeries, dateTime);
147 emit dataProvided(dataId, dataSeries, dateTime);
141 }
148 }
142 else {
149 else {
143 /// @todo ALX : debug
150 /// @todo ALX : debug
144 }
151 }
145 }
152 }
146 }
153 }
154 else {
155 qCInfo(LOG_AmdaProvider())
156 << "Request was canceled when downloading result file" << dataId;
157 }
158 };
159 auto httpFinishedLambda = [this, httpDownloadFinished, tempFile](QNetworkReply *reply,
160 QUuid dataId) noexcept {
161 qCInfo(LOG_AmdaProvider()) << "Generating url file completed" << dataId;
162 // Don't do anything if the reply was abort
163 if (reply->error() != QNetworkReply::OperationCanceledError) {
164 auto downloadFileUrl = QUrl{QString{reply->readAll()}};
165
166 // Executes request for downloading file //
147
167
168 // Creates destination file
169 if (tempFile->open()) {
170 // Executes request
171 emit requestConstructed(QNetworkRequest{downloadFileUrl}, dataId,
172 httpDownloadFinished);
173 }
174 }
175 else {
176 qCInfo(LOG_AmdaProvider()) << "Request was canceled when generating file url" << dataId;
177 }
148 };
178 };
149 auto httpFinishedLambda
150 = [this, httpDownloadFinished, tempFile](QNetworkReply *reply, QUuid dataId) noexcept {
151
152 // Don't do anything if the reply was abort
153 if (reply->error() != QNetworkReply::OperationCanceledError) {
154 auto downloadFileUrl = QUrl{QString{reply->readAll()}};
155
156
157 qCInfo(LOG_AmdaProvider())
158 << tr("TORM AmdaProvider::retrieveData downloadFileUrl:") << downloadFileUrl;
159 // Executes request for downloading file //
160
161 // Creates destination file
162 if (tempFile->open()) {
163 // Executes request
164 emit requestConstructed(QNetworkRequest{downloadFileUrl}, dataId,
165 httpDownloadFinished);
166 }
167 }
168 };
169
179
170 // //////////////// //
180 // //////////////// //
171 // Executes request //
181 // Executes request //
172 // //////////////// //
182 // //////////////// //
173 emit requestConstructed(QNetworkRequest{url}, token, httpFinishedLambda);
183 emit requestConstructed(QNetworkRequest{url}, token, httpFinishedLambda);
174 }
184 }
General Comments 0
You need to be logged in to leave comments. Login now