Разрешение отложенного тайм-аута выдает прерыватель ArgumentOutOfRangeException - PullRequest
1 голос
/ 11 января 2010

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

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)

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

1 Ответ

2 голосов
/ 11 января 2010

Немного математики

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

public OpenState(CircuitBreaker outer)
    : base(outer)
{
    DateTime now = DateTime.UtcNow;
    expiry = outer.Timeout > (DateTime.MaxValue - now) 
        ? DateTime.MaxValue
        : now + outer.Timeout;
}
...