Lazy-Timeout Auflösung Circuit Breaker wirft ArgumentOutOfRangeException
-
19-09-2019 - |
Frage
Ayende geschrieben ein Modifikation Davy Brions Leistungsschalter , wobei er die Timeout-Auflösung auf einem faulen Modell geändert.
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();
}
Doch kann der Konstruktor nicht , weil ein TimeSpan
können schnell Überlauf der Maximalwert eines DateTime
. Wenn beispielsweise die Zeitüberschreitung des Schutzschalters ist der Maximalwert einer Timespan.
System.ArgumentOutOfRangeException gefangen wurde
Message = „Die addiert oder subtrahiert Wert führt zu einer nicht darstellbaren Datetime.“
...
bei System.DateTime.op_Addition (Datetime d, Timespan t)
Wie vermeiden wir dieses Problem und halten das erwartete Verhalten?
Lösung
Sie ein wenig Mathematik
Bestimmen, ob die Timeout größer ist als der Rest des Maximalwertes eines DateTime
und die aktuellen DateTime
. Eine maximale TimeSpan
zeigt normalerweise eine funktionell unendliche timeout (so dass dies einen "einmaliger" Leistungsschalter).
public OpenState(CircuitBreaker outer)
: base(outer)
{
DateTime now = DateTime.UtcNow;
expiry = outer.Timeout > (DateTime.MaxValue - now)
? DateTime.MaxValue
: now + outer.Timeout;
}