【问题标题】:What are some implementations of Exception filtering in the Circuit Breaker pattern?断路器模式中的异常过滤有哪些实现?
【发布时间】:2011-01-03 20:17:25
【问题描述】:

Circuit Breaker 模式,来自书籍 Release It!,在远程服务失败(或恢复)时保护远程服务免受请求,并帮助客户端管理重复的远程服务失败。我喜欢Davy Brion’s stateful circuit breakerAyende’s lazy timeout fix 很干净。

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


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

【问题讨论】:

  • 这是投票还是问题?
  • "What are some implementations..." 表示这应该是一个 wiki。

标签: c# exception-handling circuit-breaker


【解决方案1】:

按谓词过滤

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

【讨论】:

    【解决方案2】:

    过滤哪些类型会增加计数

    您的第一个想法可能是使用泛型 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;
        }
    }
    

    【讨论】:

      【解决方案3】:

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

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2014-01-18
        • 2021-04-11
        • 1970-01-01
        • 2016-08-23
        • 1970-01-01
        • 2016-03-15
        • 2013-05-21
        • 1970-01-01
        相关资源
        最近更新 更多