|
| 1 | +import 'dart:async'; |
| 2 | +import 'dart:math' as math; |
| 3 | + |
| 4 | +import 'package:custom_supabase_drift_sync/core/error_handling.dart'; |
| 5 | + |
| 6 | +/// Custom retry function that attempts with a specific delay sequence |
| 7 | +/// [500ms, 1000ms, 2000ms, 2000ms, 2000ms] plus randomization factor |
| 8 | +Future<T> sequenceRetry<T>( |
| 9 | + FutureOr<T> Function() fn, { |
| 10 | + List<Duration> delaySequence = const [ |
| 11 | + Duration(milliseconds: 500), |
| 12 | + Duration(milliseconds: 1000), |
| 13 | + Duration(milliseconds: 2000), |
| 14 | + Duration(milliseconds: 2000), |
| 15 | + Duration(milliseconds: 2000), |
| 16 | + Duration(milliseconds: 2000), |
| 17 | + Duration(milliseconds: 3000), |
| 18 | + Duration(milliseconds: 3000), |
| 19 | + Duration(milliseconds: 4000), |
| 20 | + Duration(milliseconds: 4000), |
| 21 | + Duration(milliseconds: 5000), |
| 22 | + Duration(milliseconds: 5000), |
| 23 | + Duration(milliseconds: 5000), |
| 24 | + Duration(milliseconds: 5000), |
| 25 | + Duration(milliseconds: 5000), |
| 26 | + ], |
| 27 | + double randomizationFactor = 0.25, |
| 28 | +}) async { |
| 29 | + final random = math.Random(); |
| 30 | + var attempt = 0; |
| 31 | + |
| 32 | + while (true) { |
| 33 | + try { |
| 34 | + return await fn(); |
| 35 | + } catch (e) { |
| 36 | + attempt++; |
| 37 | + |
| 38 | + // If we've exhausted all retries, rethrow the exception |
| 39 | + if (attempt >= delaySequence.length) { |
| 40 | + E.t.debug('Max attempts reached: $attempt'); |
| 41 | + rethrow; |
| 42 | + } |
| 43 | + |
| 44 | + // Get the base delay for this attempt |
| 45 | + final baseDelay = delaySequence[attempt - 1]; |
| 46 | + |
| 47 | + // Apply randomization |
| 48 | + final randomized = |
| 49 | + 1.0 + randomizationFactor * (random.nextDouble() * 2 - 1); |
| 50 | + final delay = Duration( |
| 51 | + milliseconds: (baseDelay.inMilliseconds * randomized).round()); |
| 52 | + |
| 53 | + E.t.debug( |
| 54 | + 'Attempt $attempt failed, retrying in ${delay.inMilliseconds}ms'); |
| 55 | + // Wait before the next attempt |
| 56 | + await Future.delayed(delay); |
| 57 | + } |
| 58 | + } |
| 59 | +} |
0 commit comments