risoluzione timeout Pigro Circuit Breaker sta gettando ArgumentOutOfRangeException
-
19-09-2019 - |
Domanda
un modifica magnetotermico di Davy Brion, dove egli cambiato la risoluzione di timeout ad un modello pigro.
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();
}
Tuttavia, il costruttore può fallire perché un TimeSpan
può traboccare rapidamente il valore massimo di un DateTime
. Ad esempio, quando timeout del interruttore è il valore massimo di un periodo.
System.ArgumentOutOfRangeException è stato catturato
Messaggio = "I risultati di valore aggiunto o sottratto in un DateTime non-rappresentabile".
...
a System.DateTime.op_Addition (DateTime d, TimeSpan t)
Come possiamo evitare questo problema e mantenere il comportamento previsto?
Soluzione
fare un po 'di matematica
Determinare se il timeout è maggiore rispetto al resto del valore massimo di un DateTime
e DateTime
corrente. Un TimeSpan
massimo indica generalmente un timeout funzionalmente infinito (rendendo questa "una tantum" salvavita).
public OpenState(CircuitBreaker outer)
: base(outer)
{
DateTime now = DateTime.UtcNow;
expiry = outer.Timeout > (DateTime.MaxValue - now)
? DateTime.MaxValue
: now + outer.Timeout;
}