using System.Collections.Generic;
using System.Threading.Tasks;
using Polly.CircuitBreaker;
using Polly.Contrib.WaitAndRetry;
public static async Task Main()
var strategy = Policy.WrapAsync<HttpResponseMessage>(RetryScenario1(), RetryScenario2(), RetryScenario3(), CircuitBreaker());
await strategy.ExecuteAsync(() => Task.FromResult(new HttpResponseMessage(HttpStatusCode.Unauthorized)));
static IAsyncPolicy<HttpResponseMessage> RetryScenario1()
=> Policy<HttpResponseMessage>
.HandleResult(r => r.StatusCode == HttpStatusCode.Unauthorized)
.Or<BrokenCircuitException>()
.WaitAndRetryAsync(sleepDurations: Backoff.ConstantBackoff(delay: TimeSpan.FromSeconds(1), retryCount: 3),
onRetry: (ex, ts) => Console.WriteLine("OnRetry for 401"));
static IAsyncPolicy<HttpResponseMessage> RetryScenario2()
=> Policy<HttpResponseMessage>
.HandleResult(r => r.StatusCode == HttpStatusCode.TooManyRequests)
.Or<BrokenCircuitException>()
.WaitAndRetryAsync(sleepDurations: Backoff.ExponentialBackoff(initialDelay: TimeSpan.FromSeconds(1), retryCount: 3),
onRetry: (ex, ts) => Console.WriteLine("OnRetry for 429"));
static IAsyncPolicy<HttpResponseMessage> RetryScenario3()
=> Policy<HttpResponseMessage>
.HandleResult(r => r.StatusCode == HttpStatusCode.BadGateway || r.StatusCode == HttpStatusCode.GatewayTimeout)
.Or<BrokenCircuitException>()
.WaitAndRetryAsync(sleepDurations: Backoff.ConstantBackoff(delay: TimeSpan.FromSeconds(5), retryCount: 3),
onRetry: (ex, ts) => Console.WriteLine("OnRetry for 502, 504"));
static List<HttpStatusCode> retryable = [ HttpStatusCode.Unauthorized, HttpStatusCode.TooManyRequests, HttpStatusCode.BadGateway, HttpStatusCode.GatewayTimeout ];
static IAsyncPolicy<HttpResponseMessage> CircuitBreaker()
=> Policy<HttpResponseMessage>
.HandleResult(r => retryable.Contains(r.StatusCode))
.CircuitBreakerAsync(handledEventsAllowedBeforeBreaking: 2,
durationOfBreak: TimeSpan.FromSeconds(10),
onBreak: (r, ts) => Console.WriteLine("OnBreak"),
onReset: () => Console.WriteLine("OnReset"),
onHalfOpen: () => Console.WriteLine("OnHalfOpen"));