public override void OnActionFailure(DelegateResult <TResult> outcome, Context context) { using (TimedLock.Lock(_lock)) { _lastOutcome = outcome; switch (_circuitState) { case CircuitState.HalfOpen: Break_NeedsLock(context); return; case CircuitState.Closed: _metrics.IncrementFailure_NeedsLock(); var healthCount = _metrics.GetHealthCount_NeedsLock(); int throughput = healthCount.Total; if (throughput >= _minimumThroughput && ((double)healthCount.Failures) / throughput >= _failureThreshold) { Break_NeedsLock(context); } break; case CircuitState.Open: case CircuitState.Isolated: _metrics.IncrementFailure_NeedsLock(); break; // A failure call result may arrive when the circuit is open, if it was placed before the circuit broke. We take no action beyond tracking the metric; we do not want to duplicate-signal onBreak; we do not want to extend time for which the circuit is broken. We do not want to mask the fact that the call executed (as replacing its result with a Broken/IsolatedCircuitException would do). default: throw new InvalidOperationException("Unhandled CircuitState."); } } }
public override void OnActionFailure(DelegateResult <TResult> outcome, Context context) { using (TimedLock.Lock(_lock)) { _lastOutcome = outcome; if (_circuitState == CircuitState.HalfOpen) { Break_NeedsLock(context); return; } _metrics.IncrementFailure_NeedsLock(); var healthCount = _metrics.GetHealthCount_NeedsLock(); int throughput = healthCount.Total; if (throughput >= _minimumThroughput && ((double)healthCount.Failures) / throughput >= _failureThreshold) { Break_NeedsLock(context); } } }