Lazy resolución de tiempo de espera Circuit Breaker es tirar ArgumentOutOfRangeException
-
19-09-2019 - |
Pregunta
una modificación a circuito interruptor de Davy Brion, en el que se cambiado la resolución de tiempo de espera a un modelo perezoso.
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();
}
Sin embargo, el constructor puede fallar porque un TimeSpan
puede desbordar rápidamente el valor máximo de un DateTime
. Por ejemplo, cuando el tiempo de espera del interruptor de circuito es el valor máximo de un intervalo de tiempo.
System.ArgumentOutOfRangeException fue capturado
Mensaje = "Los resultados de valor añadido o se resta en un DateTime un-representable."
...
a System.DateTime.op_Addition (DateTime d, TimeSpan t)
¿Cómo podemos evitar este problema y mantener el comportamiento esperado?
Solución
hacer un poco de matemáticas
Determinar si el tiempo de espera es mayor que el resto del valor máximo de un DateTime
y la DateTime
actual. A TimeSpan
máximo por lo general indica un tiempo de espera funcionalmente infinito (haciendo de este un interruptor de circuito "de una sola vez").
public OpenState(CircuitBreaker outer)
: base(outer)
{
DateTime now = DateTime.UtcNow;
expiry = outer.Timeout > (DateTime.MaxValue - now)
? DateTime.MaxValue
: now + outer.Timeout;
}