Quais são algumas implementações de filtragem Exceção no padrão disjuntor?
-
19-09-2019 - |
Pergunta
O padrão disjuntor , a partir do livro lançamento It ! , protege um serviço remoto de pedidos ao mesmo tempo que está a falhar (ou recuperação) e ajuda o cliente a gerenciar repetida falha do serviço remoto. I como stateful disjuntor de Davy Brion e o Ayende preguiçoso tempo limite correção é muito limpo .
No entanto, eu não vi um monte de implementações de filtragem que exceções irá causar um aumento na contagem de falha de um disjuntor.
Não se preocupe em mostrar bloqueio, a menos que sua aplicação é particularmente dependente de bloqueio inteligente. FYI, Phil Haack parece ter a última versão do TimedLock , usado em artigos de Davy Brion.
Solução
Filtrar por predicado
A predicado pode fornecer critérios estendidos e lógica de filtragem.
public void AttemptCall(Action action, Predicate<Exception> match)
{
try
{
action();
}
catch(Exception e)
{
if(match(e))
state.ActUponException(e);
throw;
}
}
Por exemplo, você pode querer aumentar o disjuntor somente em um WebException
causado por um tempo limite.
circuitBreaker.AttemptCall(() => service.DoWork(), e =>
{
WebException local = e as WebException;
if(local == null)
return false;
return local.Status == WebExceptionStatus.Timeout;
});
Outras dicas
Filtro quais tipos irá aumentar a contagem
Seu primeiro pensamento pode ser para construir uma chamada de método genérico com um bloco try... catch
genérico. No entanto, o abaixo não irá funcionar devido a um .NET bug , consulte estas perguntas para mais informações.
public void AttemptCall<TException>(Action action)
where TException : Exception
{
try
{
action();
}
catch(TException e)
{
state.ActUponExcpetion(e);
throw;
}
}
Você precisa capturar todas as exceções e investigar o tipo.
public void AttemptCall<TException>(Action action)
where TException : Exception
{
try
{
action();
}
catch(TException e)
{
if(e is TException)
state.ActUponExcpetion(e);
throw;
}
}
Filtro quais tipos não vai aumentar a contagem
Tim Ross escreveu sobre este .
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;
}
}