retry<T> method
Implementation
Future<T> retry<T>(
FutureOr<T> Function() fn, {
FutureOr<bool> Function(Exception)? retryIf,
FutureOr<void> Function(Exception)? onRetry,
}) async {
final deadline = DateTime.now().add(maxTime);
var attempt = 0;
while (true) {
attempt++;
try {
return await fn();
} on Exception catch (e) {
int? retryAfter = -1;
if (e is InfluxDBException) {
retryAfter = e.retryAfter;
}
// Bail out immediately if not retryable
if (retryIf != null && !(await retryIf(e))) {
rethrow;
}
// Bail out when max number of retries was reached (first attempt is not counted as a retry)
if (attempt >= maxRetries + 1) {
throw RetryException('Maximum retry attempts reached', e);
}
// Bail out when max retry time is exceeded
if (DateTime.now().isAfter(deadline)) {
throw RetryException(
'Maximum retry time (${maxTime.inMilliseconds}ms) exceeded', e);
}
// Execute handler if any
if (onRetry != null) {
await onRetry(e);
}
// Sleep for suggested delay but respect timeout
final duration = delay(attempt, retryAfter, deadline);
logPrint('The retryable error occurred during request. '
'Reason: $e Attempt: $attempt '
'Next retry in: ${duration.inSeconds}s. (${duration.toString()})');
await Future.delayed(duration);
}
}
}