The circuit breaker pattern is a software pattern inspired by the electrical circuit breaker.
It's an elegant, easy technique to help you handle failure scenarios, especially where you have code that calls remote services such as a database or a web service, or any service that might become unavailable or non-responsive.
That includes every app I've worked on over the last 10 years :)
You can learn about it in the Release It! book. I've been reading around a little, and thought it might be useful to write about what I've seen so far.
####Lokad Shared Libraries
One interesting resources is the blog of Rinat Abdulling. He presents some code for handling exceptions, timeouts, retries and circuit breakers. This code is based on the Open Source Lokad project for .NET.
Elegant Retries
For example, if you've ever wanted to write code that can perform 3 retries before raising an exception, take a look at this sample:
// setup a policy for retrying any given action 3 times
var retryPolicy = ActionPolicy.Handle<ServiceCallException>().Retry(3);
try
{
// make the service call using that policy. If failure happens, it will suppress the exception
// and retry 3 times before finally raising it
retryPolicy.Do( () => paymentGatewayFacade.Makepayment( paymentInfo ) );
}
catch(ServiceCallException)
{
log.Error(@"Payment failed after 3 retries,
the service might be unavailable.");
//insert code to elegantly handle failure
}
Nice huh!
Circuit Breaker
Alternatively, you could use a circuit breaker which prevents your system from hammering the remote resource by cutting out after a number of failures, and then resetting after a period of time.
// setup a policy that stops subsequent calls for a minute after 5 failures (no retries)
var circuitBreakerPolicy =
ActionPolicy.Handle<ServiceCallException>().CircuitBreaker(1.Minutes, 5);
string gravatar = null;
try
{
// get my gravatar, fail nicely
gravatar =
circuitBreakerPolicy.Get(() => gravatarFacade.GetUrl( "tobin" ));
}
catch(ServiceCallException)
{
gravatar = "http://localhost/images/gravatar_not_available.png");
log.Warning(@"Gravatar service failed.
We stop trying to get them for a minute
after 5 failures in a row."
}
I've always handled remote service call failures with ad-hoc, inconsistent code. Not any more!
I believe these kinds of tool and patterns should be in every developers tool-chest, because we deal with remote service calls so often.
####The Blog of Tim Ross
As a final mention, Tim Ross gives a good explanation here, with some sample C# code. Check out his updated version too.