17 : Who's a pretty boy then?
13 May 2022Polly - do you need it? Should you be using it? When can you use it? How do you use it? We'll be answering all these questions and discovering (nearly) all there is to know about Polly in this episode.
Random fact
There are around 393 species of Parrots
There are lots of different types of parrots out there, most of them are found in tropical and subtropical surroundings.
There are 3 different families of parrots: the Psittacoidea, which are known as true parrots. Cacatuoidea, which are cockatoos and Strigopoidea, which are New Zealand parrots.
Rowan: Don’t forget my favourite parrot - the Flamin Galah! 😆
Introduction
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 Fall-back in a fluent and thread-safe manner.
So what does that mean to me?!
What does it do
Reduce the number of exceptions or errors shown to users
Handles transient error conditions
An error that only lasts a few seconds - network issues
Makes software more resilient by handling faults - typically when interacting with external resources like dbs, hard disks, http calls, 3rd party services etc
Does this by introducing an abstraction that executes a given operation delegate, whether it be synchronous or Asynchronous, using one or more Policies.
Resilience policies
Polly offers multiple resilience policies:
- You are not limited to just one policy. Polly support policy registries, via named policies, that allow you to configure multiple policies that can be used in combination with each other throughout your app if needed.
When would you think about using something like Polly
Anytime you’re calling something outside of your control?
Why not just use a try/catch and a while loop to keep retrying?
- you’d have to write that yourself
- the simple version would be front and centre of you codebase, tightly coupled flow
- might be harder to test
- might be harder to change
- If you wanted to progress to something a bit more sophisticated like one of the strategies already mentioned (upgrade to bulkhead / circuit breaker / backoff), that would require changing code, getting it right, retesting, potentially introducing other problems in the process. The Polly abstraction gets out of the way of your logic, nice and decoupled
- You’d have to write tests around your retry logic
- Why would you build this type of thing yourself?!
How do you use it?
Install package from NuGet
Think about the type of policy / policies that you need to apply
Write some code to write up your calls to external services or 3rd party libraries.
Policy.Handle<WebException>()
.RetryForever()
.Execute( () ⇒ { your code here } );
The .Net Core Http Client even integrates with it, to allow you to configure the client to use specific Polly policies
How to configure a http client to use exponential backoff calls with Polly:
- Use package Microsoft.Extensions.Http.Polly
- Use the
AddPolicyHandler
extension method when configuring the HttpClient inStartup.cs
- Point to your specific retry policy
//1. reference the extension package Microsoft.Extensions.Http.Polly
//ConfigureServices() - Startup.cs
services.AddHttpClient<IBasketService, BasketService>()
.SetHandlerLifetime(TimeSpan.FromMinutes(5)) //Set lifetime to five minutes
.AddPolicyHandler(GetRetryPolicy());
static IAsyncPolicy<HttpResponseMessage> GetRetryPolicy()
{
return HttpPolicyExtensions
.HandleTransientHttpError()
.OrResult(msg => msg.StatusCode == System.Net.HttpStatusCode.NotFound)
.WaitAndRetryAsync(6, retryAttempt => TimeSpan.FromSeconds(Math.Pow(2,
retryAttempt)));
}
You can even add a jitter strategy to the retry policy:
- A regular Retry policy can affect your system in cases of high concurrency and scalability and under high contention.
- To overcome peaks of similar retries coming from many clients in partial outages, a good workaround is to add a jitter strategy to the retry algorithm/policy
- This will apply smooth and evenly distributed retry intervals applied with a well-controlled median initial retry delay on an exponential backoff.
- This approach helps to spread out the spikes when the issue arises
var delay = Backoff.DecorrelatedJitterBackoffV2(medianFirstRetryDelay: TimeSpan.FromSeconds(1), retryCount: 5);
var retryPolicy = Policy
.Handle<FooException>()
.WaitAndRetryAsync(delay);
Wrap up
A mature framework even used by Microsoft - well worth using in pretty much any project!
Polly targets .NET Standard 1.1 (coverage: .NET Core 1.0, Mono, Xamarin, UWP, WP8.1+) and .NET Standard 2.0+ (coverage: .NET Core 2.0+, .NET Core 3.0, and later Mono, Xamarin and UWP targets). The NuGet package also includes direct targets for .NET Framework 4.6.1 and 4.7.2.
https://github.com/App-vNext/Polly
Loads of examples on the GitHub site to get you started
OS project/utility of the week
Spectre.Console
https://github.com/spectreconsole/spectre.console
Spectre.Console is a .NET Standard 2.0
library that makes it easier to create beautiful console applications.
Spectre.Console.AnsiConsole Features
- Easily output text with different colours and even styles such as bold, italic and blinking with a Rich inspired markup language.
- Supports
3
/4
/8
/24
bit colours in the terminal with auto-detection of the current terminal's capabilities. - Render complex widgets such as tables, trees, and even ASCII images.
- Display progress for long running tasks with live displays of progress and status controls.
- Prompt user input with strongly typed text input or via single-item select and multiple item select controls.
- Format .NET exceptions with custom colour coded themes and styles.
- Written with unit testing in mind.