Sometimes, your app loses network connectivity and can't fetch data. Sometimes the database connection for one part of your app goes down and web requests back up, causing the whole app to slow down. In short, errors happen. Part of software development is specifying how errors should be handled and how to prevent their effects from spreading too far.
Polly is a .NET library that allows you to do exactly that. It provides a simple API to set up common fault-handling policies. If necessary, you can combine them into more complex policies. You can specify reactive and proactive policies.
Let's see some examples.
A reactive policy: WaitAndRetry
let waitAndRetry =
Policy
.Handle<HttpRequestException>()
.WaitAndRetry [
TimeSpan.FromSeconds 1.
TimeSpan.FromSeconds 2.
TimeSpan.FromSeconds 4.
TimeSpan.FromSeconds 8.
]
let fromService = waitAndRetry.Execute getFromAnotherService
This code will react to an error by retrying up to four times, waiting between each attempt.
A proactive policy: Bulkhead
// This policy instance should be shared in all the places you want to use the policy.
let bulkhead =
Policy
.Bulkhead(
maxParallelization = 5,
maxQueuingActions = 10,
onBulkheadRejected = sendErrorNotification)
let fromDb = bulkhead.Execute readDataFromDb
This code will only allow 5 actions to run in parallel, queuing up to 10 more. Once the queue has backed up, sendErrorNotification
will be invoked. This pre-emptively guards against a faulted DB from taking down the whole app.
Combining policies: Wrap
let wrap = Policy.Wrap(bulkhead, waitAndRetry)
let data = wrap.Execute readDataFromDb
The code here will try to read data from the database, waiting and retrying if it fails. The first attempt is made according to the rules of the bulkhead
policy.
Summary
Polly makes it easy to specify and execute policies for fault handling and resilience.
If you want to learn more, there are plenty of great examples in the Polly GitHub README, which links to pages in the wiki if you're after something deeper. There's also the Polly.Contrib GitHub organisation that hosts community-contributed repositories with some useful extensions.