Polly
Polly is a .NET resilience and transient-fault-handling library that allows developers to express policies such as Retry, Circuit Breaker, Timeout, Bulkhead Isolation, and Fallback in a fluent and thread-safe manner. From version 6.0.1, Polly targets .NET Standard 1.1 and 2.0+.
Install / Use
/learn @App-vNext/PollyREADME
Polly
Polly is a .NET resilience and transient-fault-handling library that allows developers to express resilience strategies such as Retry, Circuit Breaker, Hedging, Timeout, Rate Limiter and Fallback in a fluent and thread-safe manner.
<!-- markdownlint-disable MD042 -->![NuGet][package-badge-version] ![NuGet Downloads][package-badge-downloads]
<!-- markdownlint-enable MD042 --><img align="right" src="https://github.com/dotnet/swag/raw/main/logo/dotnetfoundation_v4_small.png" width="100" alt="The .NET Foundation logo" /> We are a member of the .NET Foundation!
Keep up to date with new feature announcements, tips & tricks, and other news through www.thepollyproject.org
<!-- markdownlint-disable MD042 --> <!-- markdownlint-enable MD034 -->[!IMPORTANT] This documentation describes the new Polly v8 API. If you are using the v7 API, please refer to the previous version of the documentation.
NuGet Packages
| Package | Latest Version | About |
| :---------- | :----------------- | :-------- |
| Polly.Core | | The core abstractions and built-in strategies. |
|
Polly.Extensions | | Telemetry and dependency injection support. |
|
Polly.RateLimiting | | Integration with
System.Threading.RateLimiting APIs. |
| Polly.Testing | | Testing support for Polly libraries. |
|
Polly | | This package contains the legacy API exposed by versions of the Polly library before version 8. |
Documentation
This README aims to give a quick overview of some Polly features - including enough to get you started with any resilience strategy. For deeper detail on any resilience strategy, and many other aspects of Polly, be sure also to check out [pollydocs.org][polly-docs].
Quick start
To use Polly, you must provide a callback and execute it using resilience pipeline. A resilience pipeline is a combination of one or more resilience strategies such as retry, timeout, and rate limiter. Polly uses builders to integrate these strategies into a pipeline.
To get started, first add the Polly.Core package to your project by running the following command:
dotnet add package Polly.Core
You can create a ResiliencePipeline using the ResiliencePipelineBuilder class as shown below:
// Create an instance of builder that exposes various extensions for adding resilience strategies
ResiliencePipeline pipeline = new ResiliencePipelineBuilder()
.AddRetry(new RetryStrategyOptions()) // Add retry using the default options
.AddTimeout(TimeSpan.FromSeconds(10)) // Add 10 seconds timeout
.Build(); // Builds the resilience pipeline
// Execute the pipeline asynchronously
await pipeline.ExecuteAsync(static async token => { /* Your custom logic goes here */ }, cancellationToken);
<!-- endSnippet -->
Dependency injection
If you prefer to define resilience pipelines using IServiceCollection, you'll need to install the Polly.Extensions package:
dotnet add package Polly.Extensions
You can then define your resilience pipeline using the AddResiliencePipeline(...) extension method as shown:
var services = new ServiceCollection();
// Define a resilience pipeline with the name "my-pipeline"
services.AddResiliencePipeline("my-pipeline", builder =>
{
builder
.AddRetry(new RetryStrategyOptions())
.AddTimeout(TimeSpan.FromSeconds(10));
});
// Build the service provider
var serviceProvider = services.BuildServiceProvider();
// Retrieve a ResiliencePipelineProvider that dynamically creates and caches the resilience pipelines
var pipelineProvider = serviceProvider.GetRequiredService<ResiliencePipelineProvider<string>>();
// Retrieve your resilience pipeline using the name it was registered with
ResiliencePipeline pipeline = pipelineProvider.GetPipeline("my-pipeline");
// Alternatively, you can use keyed services to retrieve the resilience pipeline
pipeline = serviceProvider.GetRequiredKeyedService<ResiliencePipeline>("my-pipeline");
// Execute the pipeline
await pipeline.ExecuteAsync(static async token =>
{
// Your custom logic goes here
});
<!-- endSnippet -->
Resilience strategies
Polly provides a variety of resilience strategies. Alongside the comprehensive guides for each strategy, the wiki also includes an overview of the role each strategy plays in resilience engineering.
Polly categorizes resilience strategies into two main groups:
Reactive
These strategies handle specific exceptions that are thrown, or results that are returned, by the callbacks executed through the strategy.
| Strategy | Premise | AKA | Mitigation | | ------------- | ------------- | -------------- | ------------ | | Retry family | Many faults are transient and may self-correct after a short delay. | Maybe it's just a blip | Allows configuring automatic retries. | | Circuit-breaker family | When a system is seriously struggling, failing fast is better than making users/callers wait. <br/><br/>Protecting a faulting system from overload can help it recover. | Stop doing it if it hurts <br/><br/>Give that system a break | Breaks the circuit (blocks executions) for a period, when faults exceed some pre-configured threshold. | | Fallback | Things will still fail - plan what you will do when that happens. | Degrade gracefully | Defines an alternative value to be returned (or action to be executed) on failure. | | Hedging | Things can be slow sometimes, plan what you will do when that happens. | Hedge your bets | Executes parallel actions when things are slow and waits for the fastest one. |
Proactive
Unlike reactive strategies, proactive strategies do not focus on handling errors, but the callbacks might throw or return. They can make proactive decisions to cancel or reject the execution of callbacks.
| Strategy | Premise | AKA | Prevention | | ----------- | ------------- | -------------- | ------------ | | Timeout | Beyond a certain wait, a success result is unlikely. | Don't wait forever | Guarantees the caller won't have to wait beyond the timeout. | | Rate Limiter | Limiting the rate a system handles requests is another way to control load. <br/> <br/> This can apply to the way your system accepts incoming calls, and/or to the way you call downstream services. | Slow down a bit, will you? | Constrains executions to not exceed a certain rate. |
Visit resilience strategies docs to explore how to configure individual resilience strategies in more detail.
Retry
<!-- snippet: retry -->// Retry using the default options.
// See https://www.pollydocs.org/strategies/retry#defaults for defaults.
var optionsDefaults = new RetryStrategyOptions();
// For instant retries with no delay
var optionsNoDelay = new RetryStrategyOptions
{
Delay = TimeSpan.Zero
};
// For advanced control over the retry behavior, including the number of attempts,
// delay between retries, and the types of exceptions to handle.
var optionsComplex = new RetryStrategyOptions
{
ShouldHandle = new PredicateBuilder().Handle<SomeExceptionType>(),
BackoffType = DelayBackoffType.Exponential,
UseJitter = true, // Adds a random factor to the delay
MaxRetryAttempts = 4,
Delay = TimeSpan.FromSeconds(3),
};
// To use a custom function to generate

