Circuit Breaker模式中的异常过滤有哪些实现?

时间:2010-01-11 17:06:02

标签: c# exception-handling circuit-breaker

书籍Release It!中的断路器模式可保护远程服务在发生故障(或恢复)时免受请求的影响,并帮助客户端管理重复的远程服务故障。我喜欢Davy Brion’s stateful circuit breakerAyende’s lazy timeout fix非常干净。

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


不要担心显示锁定,除非您的实现特别依赖于聪明的锁定。仅供参考,Phil Haack似乎有latest version of TimedLock,用于Davy Brion的文章。

3 个答案:

答案 0 :(得分:3)

按谓词过滤

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

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;
    });

答案 1 :(得分:1)

过滤哪些类型会增加计数

您首先想到的是使用通用try... catch块构造泛型方法调用。但是,由于a .NET bug,以下内容无效,请参阅these questions了解详情。

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;
    }
}

答案 2 :(得分:1)

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

Tim Ross wrote about this

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;
     }
}