The Circuit Breaker pattern, from the book Release It!, protects a remote service from requests while it is failing (or recovering) and helps the client manage repeated remote service failure. I like Davy Brion’s stateful circuit breaker and Ayende’s lazy timeout fix is very clean.
However, I have not seen a lot of implementations of filtering which exceptions will cause an increase in the failure count of a circuit breaker.
Don't worry about showing locking, unless your implementation is particularly dependent on clever locking. FYI, Phil Haack appears to have the latest version of TimedLock, used in Davy Brion's articles.
A predicate can provide extended criteria and filtering logic.
public void AttemptCall(Action action, Predicate<Exception> match)
{
try
{
action();
}
catch(Exception e)
{
if(match(e))
state.ActUponException(e);
throw;
}
}
For example, you may want to increase the circuit breaker only on a WebException
caused by a timeout.
circuitBreaker.AttemptCall(() => service.DoWork(), e =>
{
WebException local = e as WebException;
if(local == null)
return false;
return local.Status == WebExceptionStatus.Timeout;
});