public static async Task ExecuteAsync(CancellationToken cancellationToken) { Console.WriteLine(typeof(AsyncDemo03_WaitAndRetryNTimes_WithEnoughRetries).Name); Console.WriteLine("======="); // Let's call a web api service to make repeated requests to a server. // The service is programmed to fail after 3 requests in 5 seconds. var client = new HttpClient(); int eventualSuccesses = 0; int retries = 0; int eventualFailures = 0; // Define our policy: var policy = Policy.Handle <Exception>().WaitAndRetryAsync( retryCount: 15, // Retry up to 15 times! - should be enough that we eventually succeed. sleepDurationProvider: attempt => TimeSpan.FromMilliseconds(200), // Wait 200ms between each try. onRetry: (exception, calculatedWaitDuration) => // Capture some info for logging! { // This is your new exception handler! // Tell the user what they've won! ConsoleHelper.WriteLineInColor("Policy logging: " + exception.Message, ConsoleColor.Yellow); retries++; }); int i = 0; // Do the following until a key is pressed while (!Console.KeyAvailable && !cancellationToken.IsCancellationRequested) { i++; try { // Retry the following call according to the policy - 15 times. await policy.ExecuteAsync(async token => { // This code is executed within the Policy // Make a request and get a response string msg = await client.GetStringAsync(Configuration.WEB_API_ROOT + "/api/values/" + i); // Display the response message on the console ConsoleHelper.WriteLineInColor("Response : " + msg, ConsoleColor.Green); eventualSuccesses++; }, cancellationToken); } catch (Exception e) { ConsoleHelper.WriteLineInColor("Request " + i + " eventually failed with: " + e.Message, ConsoleColor.Red); eventualFailures++; } // Wait half second before the next request. await Task.Delay(TimeSpan.FromSeconds(0.5), cancellationToken); } Console.WriteLine(""); Console.WriteLine("Total requests made : " + i); Console.WriteLine("Requests which eventually succeeded : " + eventualSuccesses); Console.WriteLine("Retries made to help achieve success: " + retries); Console.WriteLine("Requests which eventually failed : " + eventualFailures); }
public static async Task Execute(CancellationToken cancellationToken) { Console.WriteLine(typeof(AsyncDemo06_WaitAndRetryNestingCircuitBreaker).Name); Console.WriteLine("======="); // Let's call a web api service to make repeated requests to a server. // The service is programmed to fail after 3 requests in 5 seconds. var client = new HttpClient(); int eventualSuccesses = 0; int retries = 0; int eventualFailuresDueToCircuitBreaking = 0; int eventualFailuresForOtherReasons = 0; // Define our waitAndRetry policy: keep retrying with 200ms gaps. var waitAndRetryPolicy = Policy .Handle <Exception>(e => !(e is BrokenCircuitException)) // Exception filtering! We don't retry if the inner circuit-breaker judges the underlying system is out of commission! .WaitAndRetryForeverAsync( attempt => TimeSpan.FromMilliseconds(200), (exception, calculatedWaitDuration) => { // This is your new exception handler! // Tell the user what they've won! ConsoleHelper.WriteLineInColor(".Log,then retry: " + exception.Message, ConsoleColor.Yellow); retries++; }); // Define our CircuitBreaker policy: Break if the action fails 4 times in a row. var circuitBreakerPolicy = Policy .Handle <Exception>() .CircuitBreakerAsync( exceptionsAllowedBeforeBreaking: 4, durationOfBreak: TimeSpan.FromSeconds(3), onBreak: (ex, breakDelay) => { ConsoleHelper.WriteLineInColor(".Breaker logging: Breaking the circuit for " + breakDelay.TotalMilliseconds + "ms!", ConsoleColor.Magenta); ConsoleHelper.WriteLineInColor("..due to: " + ex.Message, ConsoleColor.Magenta); }, onReset: () => ConsoleHelper.WriteLineInColor(".Breaker logging: Call ok! Closed the circuit again!", ConsoleColor.Magenta), onHalfOpen: () => ConsoleHelper.WriteLineInColor(".Breaker logging: Half-open: Next call is a trial!", ConsoleColor.Magenta) ); int i = 0; // Do the following until a key is pressed while (!Console.KeyAvailable && !cancellationToken.IsCancellationRequested) { i++; Stopwatch watch = new Stopwatch(); watch.Start(); try { // Retry the following call according to the policy - 3 times. await waitAndRetryPolicy.ExecuteAsync(async token => { // This code is executed within the waitAndRetryPolicy string msg = await circuitBreakerPolicy.ExecuteAsync <String>(() => // Note how we can also Execute() a Func<TResult> and pass back the value. { // This code is executed within the circuitBreakerPolicy // Make a request and get a response return(client.GetStringAsync(Configuration.WEB_API_ROOT + "/api/values/" + i)); }); watch.Stop(); // Display the response message on the console ConsoleHelper.WriteInColor("Response : " + msg, ConsoleColor.Green); ConsoleHelper.WriteLineInColor(" (after " + watch.ElapsedMilliseconds + "ms)", ConsoleColor.Green); eventualSuccesses++; }, cancellationToken); } catch (BrokenCircuitException b) { watch.Stop(); ConsoleHelper.WriteInColor("Request " + i + " failed with: " + b.GetType().Name, ConsoleColor.Red); ConsoleHelper.WriteLineInColor(" (after " + watch.ElapsedMilliseconds + "ms)", ConsoleColor.Red); eventualFailuresDueToCircuitBreaking++; } catch (Exception e) { watch.Stop(); ConsoleHelper.WriteInColor("Request " + i + " eventually failed with: " + e.Message, ConsoleColor.Red); ConsoleHelper.WriteLineInColor(" (after " + watch.ElapsedMilliseconds + "ms)", ConsoleColor.Red); eventualFailuresForOtherReasons++; } // Wait half second await Task.Delay(TimeSpan.FromSeconds(0.5), cancellationToken); } Console.WriteLine(""); Console.WriteLine("Total requests made : " + i); Console.WriteLine("Requests which eventually succeeded : " + eventualSuccesses); Console.WriteLine("Retries made to help achieve success : " + retries); Console.WriteLine("Requests failed early by broken circuit : " + eventualFailuresDueToCircuitBreaking); Console.WriteLine("Requests which failed after longer delay: " + eventualFailuresForOtherReasons); }