polly_dart 0.0.3 copy "polly_dart: ^0.0.3" to clipboard
polly_dart: ^0.0.3 copied to clipboard

A Dart port of Polly (.NET resilience library) providing strategies like Retry, Circuit Breaker, Timeout, Rate Limiter, Hedging, and Fallback.

example/polly_dart_example.dart

import 'dart:async';
import 'dart:math';

import 'package:polly_dart/polly_dart.dart';

/// Example demonstrating various Polly resilience strategies.
void main() async {
  print('Polly Dart Examples');
  print('===================\n');

  await retryExample();
  await timeoutExample();
  await circuitBreakerExample();
  await fallbackExample();
  await hedgingExample();
  await rateLimiterExample();
  await combinedStrategiesExample();
}

/// Demonstrates retry strategy with exponential backoff.
Future<void> retryExample() async {
  print('1. Retry Strategy Example');
  print('-------------------------');

  final pipeline = ResiliencePipelineBuilder()
      .addRetry(RetryStrategyOptions(
        maxRetryAttempts: 3,
        delay: Duration(milliseconds: 500),
        backoffType: DelayBackoffType.exponential,
        useJitter: true,
        onRetry: (args) async {
          print(
              '  Retry attempt ${args.attemptNumber + 1} after ${args.delay.inMilliseconds}ms delay');
        },
      ))
      .build();

  try {
    final result = await pipeline.execute((context) async {
      print('  Executing potentially failing operation...');

      // Simulate a flaky operation (70% failure rate)
      if (Random().nextDouble() < 0.7) {
        throw Exception('Simulated transient failure');
      }

      return 'Success!';
    });

    print('  Result: $result');
  } catch (e) {
    print('  Final failure: $e');
  }

  print('');
}

/// Demonstrates timeout strategy.
Future<void> timeoutExample() async {
  print('2. Timeout Strategy Example');
  print('---------------------------');

  final pipeline =
      ResiliencePipelineBuilder().addTimeout(Duration(seconds: 2)).build();

  try {
    final result = await pipeline.execute((context) async {
      print('  Starting slow operation...');

      // Simulate a slow operation
      await Future.delayed(Duration(seconds: 3));

      return 'This should timeout';
    });

    print('  Result: $result');
  } catch (e) {
    print('  Timeout occurred: ${e.runtimeType}');
  }

  print('');
}

/// Demonstrates circuit breaker strategy.
Future<void> circuitBreakerExample() async {
  print('3. Circuit Breaker Strategy Example');
  print('-----------------------------------');

  final stateProvider = CircuitBreakerStateProvider();
  final pipeline = ResiliencePipelineBuilder()
      .addCircuitBreaker(CircuitBreakerStrategyOptions(
        failureRatio: 0.5,
        minimumThroughput: 3,
        samplingDuration: Duration(seconds: 10),
        breakDuration: Duration(seconds: 2),
        stateProvider: stateProvider,
        onOpened: (args) async {
          print('  Circuit breaker opened!');
        },
        onClosed: (args) async {
          print('  Circuit breaker closed.');
        },
      ))
      .build();

  print('  Circuit state: ${stateProvider.circuitState}');

  // Execute several failing operations to trigger circuit breaker
  for (int i = 0; i < 5; i++) {
    try {
      await pipeline.execute((context) async {
        print('  Attempt ${i + 1}...');
        throw Exception('Simulated failure');
      });
    } catch (e) {
      print('  Failed: ${e.runtimeType}');
    }

    print('  Circuit state: ${stateProvider.circuitState}');
    await Future.delayed(Duration(milliseconds: 100));
  }

  print('');
}

/// Demonstrates fallback strategy.
Future<void> fallbackExample() async {
  print('4. Fallback Strategy Example');
  print('----------------------------');

  final pipeline = TypedResiliencePipelineBuilder<String>()
      .addFallback(FallbackStrategyOptions<String>(
        fallbackAction: (args) async {
          print('  Executing fallback action...');
          return Outcome.fromResult('Fallback result');
        },
        onFallback: (args) async {
          print('  Primary operation failed, using fallback');
        },
      ))
      .build();

  try {
    final result = await pipeline.execute((context) async {
      print('  Executing primary operation...');
      throw Exception('Primary operation failed');
    });

    print('  Result: $result');
  } catch (e) {
    print('  Unexpected error: $e');
  }

  print('');
}

/// Demonstrates hedging strategy.
Future<void> hedgingExample() async {
  print('5. Hedging Strategy Example');
  print('---------------------------');

  final pipeline = TypedResiliencePipelineBuilder<String>()
      .addHedging(HedgingStrategyOptions<String>(
        maxHedgedAttempts: 2,
        delay: Duration(milliseconds: 500),
        onHedging: (args) async {
          print('  Starting hedged attempt ${args.attemptNumber + 1}...');
        },
      ))
      .build();

  final stopwatch = Stopwatch()..start();

  try {
    final result = await pipeline.execute((context) async {
      final delay = Duration(milliseconds: 800 + Random().nextInt(400));
      print(
          '  Attempt ${context.attemptNumber + 1} will take ${delay.inMilliseconds}ms');

      await Future.delayed(delay);
      return 'Result from attempt ${context.attemptNumber + 1}';
    });

    stopwatch.stop();
    print('  Result: $result');
    print('  Total time: ${stopwatch.elapsedMilliseconds}ms');
  } catch (e) {
    print('  Error: $e');
  }

  print('');
}

/// Demonstrates rate limiter strategy.
Future<void> rateLimiterExample() async {
  print('6. Rate Limiter Strategy Example');
  print('--------------------------------');

  final pipeline = ResiliencePipelineBuilder()
      .addRateLimiter(RateLimiterStrategyOptions.slidingWindow(
        permitLimit: 3,
        window: Duration(seconds: 2),
        onRejected: (args) async {
          print('  Request rejected: ${args.reason}');
        },
      ))
      .build();

  // Try to execute 5 requests rapidly
  final futures = <Future>[];
  for (int i = 0; i < 5; i++) {
    futures.add(pipeline.execute((context) async {
      print('  Request ${i + 1} executing...');
      await Future.delayed(Duration(milliseconds: 100));
      return 'Response ${i + 1}';
    }).catchError((e) {
      return 'Rejected';
    }));
  }

  final results = await Future.wait(futures);
  for (int i = 0; i < results.length; i++) {
    print('  Request ${i + 1} result: ${results[i]}');
  }

  print('');
}

/// Demonstrates combining multiple strategies.
Future<void> combinedStrategiesExample() async {
  print('7. Combined Strategies Example');
  print('------------------------------');

  final pipeline = ResiliencePipelineBuilder()
      .addRetry(RetryStrategyOptions(
        maxRetryAttempts: 2,
        delay: Duration(milliseconds: 200),
      ))
      .addTimeout(Duration(seconds: 5))
      .addCircuitBreaker(CircuitBreakerStrategyOptions(
        failureRatio: 0.8,
        minimumThroughput: 2,
      ))
      .build();

  for (int i = 0; i < 3; i++) {
    try {
      final result = await pipeline.execute((context) async {
        print('  Execution ${i + 1}, attempt ${context.attemptNumber + 1}');

        // Simulate occasional failures
        if (Random().nextDouble() < 0.6) {
          throw Exception('Simulated failure');
        }

        return 'Success on execution ${i + 1}';
      });

      print('  Result: $result');
    } catch (e) {
      print('  Failed: ${e.runtimeType}');
    }

    await Future.delayed(Duration(milliseconds: 100));
  }

  print('');
  print('Examples completed!');
}
29
likes
0
points
212
downloads

Publisher

unverified uploader

Weekly Downloads

A Dart port of Polly (.NET resilience library) providing strategies like Retry, Circuit Breaker, Timeout, Rate Limiter, Hedging, and Fallback.

Homepage
Repository (GitHub)
View/report issues

License

unknown (license)

More

Packages that depend on polly_dart