断路器模式,来自《Release It!》一书 ,在远程服务失败(或恢复)时保护远程服务免受请求,并帮助客户端管理重复的远程服务失败。我喜欢Davy Brion 的有状态断路器,而Ayende 的延迟超时修复非常干净。
但是,我还没有看到很多过滤哪些异常会导致断路器故障计数增加的实现。
不要担心显示锁定,除非您的实现特别依赖于巧妙的锁定。仅供参考,Phil Haack 似乎拥有最新版本的 TimedLock,用于 Davy Brion 的文章。
断路器模式,来自《Release It!》一书 ,在远程服务失败(或恢复)时保护远程服务免受请求,并帮助客户端管理重复的远程服务失败。我喜欢Davy Brion 的有状态断路器,而Ayende 的延迟超时修复非常干净。
但是,我还没有看到很多过滤哪些异常会导致断路器故障计数增加的实现。
不要担心显示锁定,除非您的实现特别依赖于巧妙的锁定。仅供参考,Phil Haack 似乎拥有最新版本的 TimedLock,用于 Davy Brion 的文章。
谓词可以提供扩展标准和过滤逻辑。
public void AttemptCall(Action action, Predicate<Exception> match)
{
try
{
action();
}
catch(Exception e)
{
if(match(e))
state.ActUponException(e);
throw;
}
}
例如,您可能只想在WebException
由超时引起的情况下增加断路器。
circuitBreaker.AttemptCall(() => service.DoWork(), e =>
{
WebException local = e as WebException;
if(local == null)
return false;
return local.Status == WebExceptionStatus.Timeout;
});
您的第一个想法可能是使用泛型try... catch
块构造泛型方法调用。但是,由于.NET 错误,以下内容将不起作用,请参阅这些 问题以获取更多信息。
public void AttemptCall<TException>(Action action)
where TException : Exception
{
try
{
action();
}
catch(TException e)
{
state.ActUponExcpetion(e);
throw;
}
}
您需要捕获所有异常并调查类型。
public void AttemptCall<TException>(Action action)
where TException : Exception
{
try
{
action();
}
catch(TException e)
{
if(e is TException)
state.ActUponExcpetion(e);
throw;
}
}
private readonly List<Exception> ignored = new List<Exception>();
public void Ignore<TException>()
where TException : Exception
{
Type type = typeof(TException);
if(ignored.Contains(type))
return;
ignored.Add(type);
}
public void AttemptCall(Action action)
{
try
{
action();
}
catch(Exception e)
{
if(!ignore.Contains(e.GetType()))
state.ActUponException(e);
throw;
}
}