Каковы некоторые реализации фильтрации исключений в шаблоне автоматического выключателя?
-
19-09-2019 - |
Вопрос
Тот самый Схема автоматического выключателя, из книги Отпусти Его!, защищает удаленную службу от запросов во время сбоя (или восстановления) и помогает клиенту управлять повторными сбоями удаленной службы.Мне нравится Автоматический выключатель Дэви Брайона с отслеживанием состояния и Исправление ленивого тайм-аута Айенде здесь очень чисто.
Однако я видел не так уж много реализации фильтрации какие исключения приведут к увеличению числа отказов автоматического выключателя.
Не беспокойтесь о показе блокировки, если только ваша реализация не особенно зависит от умной блокировки.К вашему сведению, у Фила Хаака, похоже, есть последняя версия TimedLock, используется в статьях Дэви Брайона.
Решение
Фильтр по предикату
A предикат может предоставлять расширенные критерии и логику фильтрации.
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;
}
}