5

断路器模式,来自《Release It!》一书 ,在远程服务失败(或恢复)时保护远程服务免受请求,并帮助客户端管理重复的远程服务失败。我喜欢Davy Brion 的有状态断路器,而Ayende 的延迟超时修复非常干净。

但是,我还没有看到很多过滤哪些异常会导致断路器故障计数增加的实现。


不要担心显示锁定,除非您的实现特别依赖于巧妙的锁定。仅供参考,Phil Haack 似乎拥有最新版本的 TimedLock,用于 Davy Brion 的文章。

4

3 回答 3

4

按谓词过滤

谓词可以提供扩展标准和过滤逻辑。

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;
    });
于 2010-01-11T17:08:00.863 回答
2

过滤哪些类型会增加计数

您的第一个想法可能是使用泛型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;
    }
}
于 2010-01-11T17:06:15.110 回答
2

过滤哪些类型不会增加计数

蒂姆罗斯写了这篇文章

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;
     }
}
于 2010-01-11T17:06:47.667 回答