QGroundControl
Ground Control Station for MAVLink Drones
Loading...
Searching...
No Matches
BulkRefreshJob.cc
Go to the documentation of this file.
1#include "BulkRefreshJob.h"
2#include "ParameterManager.h"
3
4#include "AppMessages.h"
6
7Q_DECLARE_LOGGING_CATEGORY(ParameterManagerLog)
8
9BulkRefreshJob::BulkRefreshJob(ParameterManager *mgr, int componentId, const QStringList &resolvedNames,
10 bool notifyFailure, std::function<void(const QString &)> requestFn,
11 QObject *parent)
12 : QObject(parent)
13 , _mgr(mgr)
14 , _componentId(componentId)
15 , _notifyFailure(notifyFailure)
16 , _requestFn(std::move(requestFn))
17 , _pending(QSet<QString>(resolvedNames.cbegin(), resolvedNames.cend()))
18 , _retryBaseDelayMs(QGC::runningUnitTests() ? 50 : kRetryBaseDelayMs)
19{
20 _retryTimer.setSingleShot(true);
21 connect(&_retryTimer, &QTimer::timeout, this, &BulkRefreshJob::_sendPendingRequests);
22 connect(_mgr, &ParameterManager::_paramRequestReadSuccess, this, &BulkRefreshJob::_onParamSuccess);
23 connect(_mgr, &ParameterManager::_paramRequestReadFailure, this, &BulkRefreshJob::_onParamFailure);
24 _sendPendingRequests();
25}
26
27void BulkRefreshJob::_sendPendingRequests()
28{
29 qCDebug(ParameterManagerLog) << "BulkRefreshJob: round" << _round
30 << "\u2014 firing" << _pending.count() << "requests";
31 for (const QString &name : std::as_const(_pending)) {
32 _requestFn(name);
33 }
34}
35
36void BulkRefreshJob::_onParamSuccess(int componentId, const QString &paramName, int /*paramIndex*/)
37{
38 if (componentId != _componentId) {
39 return;
40 }
41 const bool wasPending = _pending.remove(paramName);
42 const bool wasFailed = _failed.remove(paramName);
43 if (!wasPending && !wasFailed) {
44 return;
45 }
46 _checkRoundComplete();
47}
48
49void BulkRefreshJob::_onParamFailure(int componentId, const QString &paramName, int /*paramIndex*/)
50{
51 if (componentId != _componentId || !_pending.remove(paramName)) {
52 return;
53 }
54 _failed.insert(paramName);
55 _checkRoundComplete();
56}
57
58void BulkRefreshJob::_checkRoundComplete()
59{
60 if (!_pending.isEmpty()) {
61 return;
62 }
63
64 _retryTimer.stop();
65
66 if (_failed.isEmpty()) {
67 qCDebug(ParameterManagerLog) << "BulkRefreshJob: complete after round" << _round
68 << "\u2014 all params refreshed successfully";
69 deleteLater();
70 return;
71 }
72
73 if (_round < kMaxRetryRounds) {
74 const int delayMs = _retryBaseDelayMs << _round;
75 qCDebug(ParameterManagerLog) << "BulkRefreshJob: round" << _round
76 << "finished with" << _failed.count()
77 << "failures \u2014 retrying in" << delayMs << "ms";
78 _pending = std::move(_failed);
79 _failed.clear();
80 ++_round;
81 _retryTimer.start(delayMs);
82 } else {
83 qCDebug(ParameterManagerLog) << "BulkRefreshJob: complete after round" << _round
84 << "\u2014" << _failed.count() << "params still failed";
85 if (_notifyFailure) {
86 const QStringList failedList(_failed.cbegin(), _failed.cend());
87 QGC::showAppMessage(_mgr->tr("Parameter refresh failed for: %1").arg(failedList.join(QStringLiteral(", "))),
88 _mgr->tr("Parameter Bulk Refresh"));
89 }
90 deleteLater();
91 }
92}
static constexpr int kMaxRetryRounds
Number of batch-level retry rounds before giving up.
void _paramRequestReadFailure(int componentId, const QString &paramName, int paramIndex)
void _paramRequestReadSuccess(int componentId, const QString &paramName, int paramIndex)
void showAppMessage(const QString &message, const QString &title)
Modal application message. Queued if the UI isn't ready yet.
Definition AppMessages.cc:9