What is a Resilience Framework?
Polly is classed as a resilience framework. A resilience framework is a set of libraries that help an application to recover from transient or more extended failures in services or infrastructure upon which it depends. When recovery is not possible, the resilience framework will facilitate graceful degradation of your application.
Polly has been around for many years and has been tried and tested in many applications
The source code for Polly can be found on GitHub here:
Strategies – how to deal with the problems
There are a number of reactive approaches we can take with Polly:
Retry policy. This immediately retries the request some specified number of times without any delay.
Wait and Retry policy introduces a delay before each retry,
Circuit Breaker will stop all requests to an endpoint if some failure threshold is reached
Fallback returns some specified default if the request fails. Fallback is often used in conjunction with other policies. For example, if a request fails, retry it. If the retries fail, return a default with the Fallback.
Caching for a faster response and better performance.
These different processes assist when your application is suffering from a problem it can not address, like a request failure and a timeout, and you need to take some immediate action to address the issue.
Delegates can also be used with these policies, allowing you to run custom code as part of the policy.
Bulkhead Isolation to handle slow responding external services and prevents overloading, deals with resource allocation has the ability to trigger scaling and deals with load shedding (when your application stops returning requests and fails).
The bulkhead isolation is a proactive policy allow you to keep your application up and running during heavy overloading to keep your application available. This policy can also be used for resource sharing, load shedding or as a trigger for horizontal scaling.
Builds a bulkhead isolation Polly.Policy, which limits the maximum concurrency of actions executed through the policy. Imposing a maximum concurrency limits the potential of governed actions, when faulting, to bring down the system.
When an execution would cause the number of actions executing concurrently through the policy to exceed maxParallelization, the policy allows a further maxQueuingActions executions to queue, waiting for a concurrent execution slot. When an execution would cause the number of queuing actions to exceed maxQueuingActions, a Polly.Bulkhead.BulkheadRejectedException is thrown.
The Bulkhead Isolation has two parameters and an optional delegate.
maxParallelization: The maximum number of concurrent actions that may be executed through the policy.
maxQueuingActions: The maximum number of actions that may be queued, waiting for an execution slot.
onBulkheadRejectedAsync: An action to call asynchronously if the bulkhead rejects execution due to oversubscription.
When the load increases the Parallelization (execution slots get populated), when they are full then the requests fill the QueuingActions slots, when these get filled then a 500 exception is returned.
Here is an example of how to instantiate the Bulkhead policy with 2 execution slots and 4 queue slots
BulkheadPolicy<HttpResponseMessage> bulkheadIsolationPolicy = Policy.BulkheadAsync<HttpResponseMessage>(2, 4, onBulkheadRejectedAsync: OnBulkheadRejectedAsync);
For best practice when using Polly, this will depend on your need and requirements. However, i’d recommend using the Http Client Factory, as this makes coding so much easier and more flexible and so much cleaner.
Here is a simple example of using the http Client Factory:
As you can see no sign of Polly.
Everything is setup at StartUp, like this:
You can then add the polly policy to the Http Client:
Ideally, we would have a Polly for each different HTTP verbs or even for individual endpoints, to do this we need to set up a Polly Registry
Source can be found on GitHub
Good source of reference is this post: