11 , _stateName(stateName)
17 _action = std::move(action);
23 _maxRetries = maxRetries;
24 _retryDelayMsecs = delayMsecs;
30 _fallback = std::move(fallback);
36 _rollback = std::move(rollback);
42 _exhaustedBehavior = behavior;
48 _timeoutMsecs = timeoutMsecs;
56 state->setAction(_action);
57 state->setFallback(_fallback);
58 state->setRollback(_rollback);
59 state->setRetry(_maxRetries, _retryDelayMsecs);
60 state->setTimeout(_timeoutMsecs);
61 state->setExhaustedBehavior(_exhaustedBehavior);
63 _machine->registerState(state);
74 _retryTimer.setSingleShot(
true);
75 connect(&_retryTimer, &QTimer::timeout,
this, &ErrorRecoveryState::_executeAction);
77 _timeoutTimer.setSingleShot(
true);
78 connect(&_timeoutTimer, &QTimer::timeout,
this, &ErrorRecoveryState::_onTimeout);
83 _maxRetries = maxRetries;
84 _retryDelayMsecs = delayMsecs;
89 _timeoutMsecs = timeoutMsecs;
94 _exhaustedBehavior = behavior;
100 _triedFallback =
false;
101 _successPhase.clear();
103 if (_timeoutMsecs > 0) {
104 _timeoutTimer.start(_timeoutMsecs);
110void ErrorRecoveryState::_executeAction()
113 int totalAttempts = _maxRetries + 1;
115 qCDebug(QGCStateMachineLog) <<
stateName() <<
"attempt" << _currentAttempt <<
"of" << totalAttempts;
117 bool success =
false;
123 _timeoutTimer.stop();
124 _successPhase = QStringLiteral(
"primary");
125 qCDebug(QGCStateMachineLog) <<
stateName() <<
"primary action succeeded";
128 }
else if (_currentAttempt <= _maxRetries) {
130 qCDebug(QGCStateMachineLog) <<
stateName() <<
"retrying in" << _retryDelayMsecs <<
"ms";
131 emit
retrying(_currentAttempt + 1, totalAttempts);
132 _retryTimer.start(_retryDelayMsecs);
139void ErrorRecoveryState::_handleFailure()
142 if (_fallback && !_triedFallback) {
143 _triedFallback =
true;
144 qCDebug(QGCStateMachineLog) <<
stateName() <<
"trying fallback";
147 bool success = _fallback();
149 _timeoutTimer.stop();
150 _successPhase = QStringLiteral(
"fallback");
151 qCDebug(QGCStateMachineLog) <<
stateName() <<
"fallback succeeded";
162void ErrorRecoveryState::_handleExhausted()
164 _timeoutTimer.stop();
168 qCDebug(QGCStateMachineLog) <<
stateName() <<
"executing rollback";
175 switch (_exhaustedBehavior) {
177 qCDebug(QGCStateMachineLog) <<
stateName() <<
"all options exhausted, emitting error";
182 qCDebug(QGCStateMachineLog) <<
stateName() <<
"all options exhausted, continuing anyway";
187 qCWarning(QGCStateMachineLog) <<
stateName() <<
"all recovery options exhausted";
192 qCWarning(QGCStateMachineLog) <<
stateName() <<
"all recovery options exhausted, continuing";
198void ErrorRecoveryState::_onTimeout()
200 qCDebug(QGCStateMachineLog) <<
stateName() <<
"operation timed out";
ErrorRecoveryBuilder & retry(int maxRetries, int delayMsecs=1000)
ErrorRecoveryBuilder & withFallback(Action fallback)
Add a fallback action to try if primary fails.
ErrorRecoveryBuilder & withAction(Action action)
Set the primary action to execute.
ExhaustedBehavior
What to do when all recovery options are exhausted.
@ EmitAdvance
Continue anyway (skip)
@ LogAndAdvance
Log warning and continue.
@ LogAndError
Log warning and emit error()
@ EmitError
Emit error() signal (default)
ErrorRecoveryBuilder(QGCStateMachine *machine, const QString &stateName)
std::function< bool()> Action
std::function< void()> VoidAction
ErrorRecoveryBuilder & onExhausted(ExhaustedBehavior behavior)
Configure what happens when all options are exhausted.
ErrorRecoveryBuilder & withRollback(VoidAction rollback)
Add a rollback action to execute on failure.
QGCState * build()
Build and return the configured state.
ErrorRecoveryBuilder & withTimeout(int timeoutMsecs)
Set a timeout for the entire operation.
The state created by ErrorRecoveryBuilder.
void onEnter() override
Override to perform actions on state entry.
void setTimeout(int timeoutMsecs)
ErrorRecoveryState(const QString &stateName, QState *parent)
void retrying(int attempt, int maxAttempts)
void setExhaustedBehavior(ErrorRecoveryBuilder::ExhaustedBehavior behavior)
void setRetry(int maxRetries, int delayMsecs)
QString stateName() const
QGroundControl specific state machine with enhanced error handling.