resolução de tempo limite preguiçoso Circuit Breaker está jogando ArgumentOutOfRangeException
-
19-09-2019 - |
Pergunta
Ayende postou um modificação para circuito disjuntor de Davy Brion, onde ele mudou a resolução de tempo limite para um modelo preguiçoso.
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();
}
No entanto, o construtor pode falhar porque um TimeSpan
pode rapidamente transbordar o valor máximo de um DateTime
. Por exemplo, quando tempo limite do disjuntor é o valor máximo de um TimeSpan.
System.ArgumentOutOfRangeException foi pego
mensagem = "Os resultados de valor acrescentado ou subtraídas uma em datetime un-representável."
...
em System.DateTime.op_Addition (datetime d, TimeSpan t)
Como é que vamos evitar este problema e manter o comportamento esperado?
Solução
Faça um pouco de matemática
Determinar se o tempo de espera é maior do que o restante do valor máximo de um DateTime
eo DateTime
atual. A TimeSpan
máxima geralmente indica a funcionalmente infinita de tempo limite (tornando este um "one-time" do disjuntor).
public OpenState(CircuitBreaker outer)
: base(outer)
{
DateTime now = DateTime.UtcNow;
expiry = outer.Timeout > (DateTime.MaxValue - now)
? DateTime.MaxValue
: now + outer.Timeout;
}