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

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

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)

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


person Anthony Mastrean    schedule 11.01.2010    source источник


Ответы (1)


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

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

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