<PackageReference Include="Polly" Version="4.2.4" />

AdvancedCircuitController

using Polly.Utilities; using System; namespace Polly.CircuitBreaker { internal class AdvancedCircuitController : CircuitStateController { private const short NumberOfWindows = 10; internal static readonly long ResolutionOfCircuitTimer = TimeSpan.FromMilliseconds(20).Ticks; private readonly IHealthMetrics _metrics; private readonly double _failureThreshold; private readonly int _minimumThroughput; public AdvancedCircuitController(double failureThreshold, TimeSpan samplingDuration, int minimumThroughput, TimeSpan durationOfBreak, Action<Exception, TimeSpan, Context> onBreak, Action<Context> onReset, Action onHalfOpen) : base(durationOfBreak, onBreak, onReset, onHalfOpen) { object metrics; if (samplingDuration.Ticks >= ResolutionOfCircuitTimer * 10) { IHealthMetrics healthMetrics = new RollingHealthMetrics(samplingDuration, 10); metrics = healthMetrics; } else { IHealthMetrics healthMetrics = new SingleHealthMetrics(samplingDuration); metrics = healthMetrics; } _metrics = (IHealthMetrics)metrics; _failureThreshold = failureThreshold; _minimumThroughput = minimumThroughput; } public override void OnCircuitReset(Context context) { using (TimedLock.Lock(_lock)) { if (_metrics != null) _metrics.Reset_NeedsLock(); ResetInternal_NeedsLock(context); } } public override void OnActionSuccess(Context context) { using (TimedLock.Lock(_lock)) { if (_circuitState == CircuitState.HalfOpen) OnCircuitReset(context); _metrics.IncrementSuccess_NeedsLock(); } } public override void OnActionFailure(Exception ex, Context context) { using (TimedLock.Lock(_lock)) { _lastException = ex; if (_circuitState == CircuitState.HalfOpen) Break_NeedsLock(context); else { _metrics.IncrementFailure_NeedsLock(); HealthCount healthCount_NeedsLock = _metrics.GetHealthCount_NeedsLock(); int total = healthCount_NeedsLock.Total; if (total >= _minimumThroughput && (double)healthCount_NeedsLock.Failures / (double)total >= _failureThreshold) Break_NeedsLock(context); } } } } }