nextDelay method
Returns the delay to wait before the next attempt, or null to stop
retrying and let the original error propagate.
Called once per failed attempt with a fresh context.
Implementation
@override
FutureOr<Duration?> nextDelay(final RetryContext context) async {
if (context.attempt > maxAttempts) {
// No attempts remain.
return null;
}
if (context.isProcedure &&
context.isAmbiguous &&
!retryProcedureOnAmbiguousFailure) {
// Retrying a non-idempotent request the server may already have applied
// could duplicate its side effect.
return null;
}
int intervalInSeconds =
_computeExponentialBackOff(context.attempt) + _jitter;
final retryAfter = context.retryAfter;
if (retryAfter != null) {
//! Cap first, compare second. Clamping inside the branch inverted the
//! bound: a server asking for 1000s while the backoff stood at 512s
//! collapsed the wait to 60s, so a LARGER request produced a SHORTER
//! wait than plain backoff would have.
final atLeastInSeconds = math.min(
(retryAfter.inMilliseconds / 1000).ceil(),
_maxServerWaitInSeconds,
);
if (atLeastInSeconds > intervalInSeconds) {
intervalInSeconds = atLeastInSeconds;
}
}
await onExecute?.call(
RetryEvent(
retryCount: context.attempt,
intervalInSeconds: intervalInSeconds,
),
);
return Duration(seconds: intervalInSeconds);
}