NuGet Package of the Week: Polly wanna fluently express transient exception handling policies in .NET?
LOL at my own post title. Pardon me.
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.
About Newsletter
Anders, I need to follow you!
If I know this back in 2013...
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
<a href=""http://blog.jaywayco.co.uk/entity-framework-connection-resiliency/"">Entity Framework Connection Resiliency and Polly</a>
jaywayco
:)
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.
publish that you just made some days in the past? Any positive?
Comments are closed.
http://msdn.microsoft.com/en-us/library/dn589784.aspx