Ленивое разрешение тайм-аута. Автоматический выключатель выдает исключение ArgumentOutOfRangeException.

StackOverflow https://stackoverflow.com/questions/2043544

Вопрос

Айенде опубликовало модификация к Дэви Брайону автоматический выключатель, при этом он изменил разрешение тайм-аута на ленивую модель.

private readonly DateTime expiry;

public OpenState(CircuitBreaker outer)
    : base(outer)
{
    expiry = DateTime.UtcNow + outer.timeout;
}

public override void ProtectedCodeIsAboutToBeCalled()
{
    if(DateTime.UtcNow < expiry)
        throw new OpenCircuitException();

    outer.MoveToHalfOpenState();
}

Однако, конструктор может потерпеть неудачу потому что TimeSpan может быстро переполнить максимальное значение DateTime.Например, когда время ожидания автоматического выключателя равно максимальному значению TimeSpan.

Обнаружено исключение System.ArgumentOutOfRangeException.

Message="Добавленное или вычтенное значение приводит к непредставимому значению DateTime."

...

в System.DateTime.op_Addition(DateTime d, TimeSpan t)

Как нам избежать этой проблемы и сохранить ожидаемое поведение?

Это было полезно?

Решение

Посчитайте немного математики

Определите, если таймаут больше остатка максимального значения a DateTime и нынешний DateTime.Максимум TimeSpan обычно указывает функционально бесконечный тайм-аут (что делает это «одноразовым» автоматическим выключателем).

public OpenState(CircuitBreaker outer)
    : base(outer)
{
    DateTime now = DateTime.UtcNow;
    expiry = outer.Timeout > (DateTime.MaxValue - now) 
        ? DateTime.MaxValue
        : now + outer.Timeout;
}
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top