retry_with_connectivity 1.0.1
retry_with_connectivity: ^1.0.1 copied to clipboard
A reliable execution framework for Flutter that intelligently retries asynchronous operations with backoff strategies and circuit breakers.
// ignore_for_file: avoid_print
import 'dart:async';
import 'package:retry_with_connectivity/retry_with_connectivity.dart';
/// A simulated API client that demonstrates network reliability scenarios.
class SimulatedApiClient {
int _attemptCounter = 0;
Future<String> fetchImportantData() async {
_attemptCounter++;
print(
' [SimulatedApiClient] Executing request (attempt #$_attemptCounter)...');
if (_attemptCounter < 3) {
throw Exception(
'Simulated temporary network glitch (Attempt #$_attemptCounter)');
}
return 'SUCCESS: User profile data payload';
}
}
void main() async {
print('===========================================================');
print(' retry_with_connectivity (SmartRetry) Example Suite ');
print('===========================================================\n');
// -----------------------------------------------------------
// Example 1: Basic Retry with Exponential Backoff + Jitter
// -----------------------------------------------------------
print('--- Example 1: Exponential Jitter Backoff ---');
final apiClient = SimulatedApiClient();
try {
final result = await SmartRetry.run(
() => apiClient.fetchImportantData(),
policy: RetryPolicy.standard.copyWith(
baseDelay: const Duration(milliseconds: 200),
),
logger: RetryLogger.console(),
);
print('Result received: $result\n');
} catch (e) {
print('Failed after retries: $e\n');
}
// -----------------------------------------------------------
// Example 2: Circuit Breaker Protection
// -----------------------------------------------------------
print('--- Example 2: Circuit Breaker Protection ---');
final breaker = CircuitBreaker(
name: 'user_service_breaker',
config: const CircuitBreakerConfig(
failureThreshold: 2,
resetTimeout: Duration(seconds: 5),
),
onStateChange: (oldState, newState) {
print(' [CircuitBreaker Event] Transitioned: $oldState -> $newState');
},
);
// Simulate 2 failures that trip the breaker
for (int i = 1; i <= 2; i++) {
try {
await breaker.run(
() async => throw Exception('Downstream 503 Service Unavailable'));
} catch (_) {
print(' [Attempt $i] Service threw error.');
}
}
print('Current Breaker State: ${breaker.state}');
// Attempting a call while breaker is open fast-fails instantly
try {
print('Attempting operation while breaker is OPEN...');
await breaker.run(() async => 'this will not execute');
} on CircuitOpenException catch (e) {
print(' Caught expected fast-fail: ${e.message}\n');
}
// -----------------------------------------------------------
// Example 3: Offline Queue and Automatic Replay
// -----------------------------------------------------------
print('--- Example 3: Offline Queue Replay ---');
final offlineQueue = InMemoryOfflineQueue();
final processor = QueueProcessor(
queue: offlineQueue,
autoStartOnConnectivityRestored: false,
logger: RetryLogger.console(),
);
await offlineQueue.enqueue(
QueuedTask<String>(
id: 'analytics_evt_1',
tag: 'analytics',
action: () async => 'Analytics event sent!',
policy: const RetryPolicy(
maxAttempts: 2, baseDelay: Duration(milliseconds: 100)),
),
);
print('Enqueued ${await offlineQueue.length} task(s) into OfflineQueue.');
print('Manually draining queue...');
final summary = await processor.process();
print('Queue processing completed: $summary');
print('===========================================================');
}