Scott Hanselman

NuGet Package of the Week: Polly wanna fluently express transient exception handling policies in .NET?

January 13, '15 Comments [13] Posted in NuGet | NuGetPOW
Sponsored By

LOL at my own post title. Pardon me.

Install-Package Polly

Michael Wolfenden has a very clever open source library called Polly. Polly is a .NET 3.5 / 4.0 / 4.5 / PCL library that allows developers to express transient exception handling policies such as Retry, Retry Forever, Wait and Retry or Circuit Breaker in a fluent manner.

Handling exceptions can be a hassle sometimes. Not just setting the try/catches up, but deciding on the policy for the catch can make the exception management code more complex than the method itself!

Polly has a fluent interface to make expressing rules like that much easier. For example:

// Single exception type
Policy
.Handle<DivideByZeroException>()

// Single exception type with condition
Policy
.Handle<SqlException>(ex => ex.Number == 1205)

// Multiple exception types
Policy
.Handle<DivideByZeroException>()
.Or<ArgumentException>()

// Multiple exception types with condition
Policy
.Handle<SqlException>(ex => ex.Number == 1205)
.Or<ArgumentException>(ex => x.ParamName == "example")

Then you can add Retry() logic, which is fantastic.

// Retry multiple times, calling an action on each retry 
// with the current exception and retry count
Policy
.Handle<DivideByZeroException>()
.Retry(3, (exception, retryCount) =>
{
// do something
});

Even do retries with multiplicative back off!

// Retry a specified number of times, using a function to 
// calculate the duration to wait between retries based on
// the current retry attempt, calling an action on each retry
// with the current exception, duration and context provided
// to Execute()
Policy
.Handle<DivideByZeroException>()
.WaitAndRetry(
5,
retryAttempt => TimeSpan.FromSeconds(Math.Pow(2, retryAttempt)),
(exception, timeSpan, context) => {
// do something
}
);

Once you have set up a policy, you execute on it.

Policy
.Handle<SqlException>(ex => ex.Number == 1205)
.Or<ArgumentException>(ex => ex.ParamName == "example")
.Retry()
.Execute(() => DoSomething());

Polly also supports the more sophisticated "Circuit Breaker" policy. For more information on the Circuit Breaker pattern see:

Circuit breaker tries and then "Trips the circuit breaker" so you'll get a BrokenCircuitException for some amount of time. This is a great way to give an external system to chill for a minute if it's down. It also externalizes the concept so that you could theoretically handle a down database the same as you handle a down external web API.

// Break the circuit after the specified number of exceptions
// and keep circuit broken for the specified duration
Policy
.Handle<DivideByZeroException>()
.CircuitBreaker(2, TimeSpan.FromMinutes(1))

You can explore the code, of course, up on Github in the Polly repository. Go give the Polly project a star. They've recently added async support for .NET 4.5 as well!


Sponsor: Welcome this week's feed sponsor, Stackify! - The only developer-friendly solution that fully integrates .NET error & log management with application monitoring. Easily isolate issues and focus your efforts – Support less, Code more. Free trial

About Scott

Scott Hanselman is a former professor, former Chief Architect in finance, now speaker, consultant, father, diabetic, and Microsoft employee. He is a failed stand-up comic, a cornrower, and a book author.

facebook twitter subscribe
About   Newsletter
Sponsored By
Hosting By
Dedicated Windows Server Hosting by SherWeb
Tuesday, 13 January 2015 02:01:43 UTC
Timely blog post for my usage, thank you. Here is circuit breaker pattern details from MSDN
http://msdn.microsoft.com/en-us/library/dn589784.aspx
Baski
Tuesday, 13 January 2015 08:27:42 UTC
I have used Polly for a long time. Blogged about the great little framework in 2013: Automatic Retry and Circuit Breaker made easy
Tuesday, 13 January 2015 10:51:56 UTC
This is a life saver!!! Never heard of it, but always need it. I always need to do it by hand.

Anders, I need to follow you!

If I know this back in 2013...
Luiz Adilson
Tuesday, 13 January 2015 18:11:06 UTC
I must admit I've never heard about Polly before. Interesting library! It looks promising for retrying actions with exponentially growing pauses in between.
Tuesday, 13 January 2015 22:01:26 UTC
Reminds me of http://code.google.com/p/aspectf/
Clement
Wednesday, 14 January 2015 09:28:19 UTC
We have been using Polly for a bit. Good library, but I would like to see a Handles overload that takes a predicate that looks at the return value of the method being called. I quickly found myself wrapping methods to throw exceptions based on return values that indicated a failure simply so I could use Polly to apply a policy. The answer? Me (or someone) submitting a pull request with this feature!
Wednesday, 14 January 2015 15:27:36 UTC
Looks promising but beware of disposable objects and using statements
Joey Chömpff
Wednesday, 14 January 2015 17:52:40 UTC
People interested in this and writing systems on Azure should also be aware of these things that are designed specifically for Azure:

The Transient Fault Handling Application Block

http://msdn.microsoft.com/en-us/library/hh680934(v=pandp.50).aspx

Which, I'm not sure, may have been superceded by progress in this area:

Storage Client Library

http://azure.microsoft.com/blog/2014/05/22/azure-storage-client-library-retry-policy-recommendations/

And for those using a recent EF version with SQL Azure DB, look no further than this:

"When you use the Entity Framework you typically aren’t working directly with SQL connections, so you can’t use this Patterns and Practices package, but Entity Framework 6 builds this kind of retry logic right into the framework."

http://www.asp.net/aspnet/overview/developing-apps-with-windows-azure/building-real-world-cloud-apps-with-windows-azure/transient-fault-handling
Sunday, 18 January 2015 22:12:08 UTC
Heres Polly applied to EF6 connection resiliency...

<a href=""http://blog.jaywayco.co.uk/entity-framework-connection-resiliency/"">Entity Framework Connection Resiliency and Polly</a>

jaywayco
:)
Wednesday, 21 January 2015 00:40:41 UTC
It works beautifully in F# too.
Thursday, 22 January 2015 08:31:07 UTC
So glad to see Polly getting some more recognition. Came across it last year, contributed the PCL implementation because it is just an absolute killer nuget package for both both client AND server side. On client side use the RetryPolicies and server side use Circuit Breaker to prevent thundering heards. By client I mean in mobile applications w/Xamarin :-)
Thursday, 22 January 2015 08:37:13 UTC
For EF6+ & Azure when transient errors handling is batteries included, just plug them in: https://msdn.microsoft.com/en-us/data/dn456835.aspx


SetExecutionStrategy("System.Data.SqlClient", () => new SqlAzureExecutionStrategy(1, TimeSpan.FromSeconds(30)));


Which will retry instantly the first time a transient failure occurs, but will delay longer between each retry until either the max retry limit is exceeded or the total time hits the max delay. The execution strategies will only retry a limited number of exceptions that are usually transient, you will still need to handle other errors as well as catching the RetryLimitExceeded exception for the case where an error is not transient or takes too long to resolve itself.
Wednesday, 18 February 2015 08:49:34 UTC
great points altogether, you just gained a new reader. What could you recommend about your
publish that you just made some days in the past? Any positive?
Comments are closed.

Disclaimer: The opinions expressed herein are my own personal opinions and do not represent my employer's view in any way.