< Summary

Information
Class: Intentum.Runtime.Resilience.CircuitBreaker.MemoryCircuitBreaker
Assembly: Intentum.Runtime
File(s): /home/runner/work/Intentum/Intentum/src/Intentum.Runtime/Resilience/CircuitBreaker/MemoryCircuitBreaker.cs
Line coverage
100%
Covered lines: 69
Uncovered lines: 0
Coverable lines: 69
Total lines: 103
Line coverage: 100%
Branch coverage
93%
Covered branches: 15
Total branches: 16
Branch coverage: 93.7%
Method coverage

Feature is only available for sponsors

Upgrade to PRO version

Metrics

MethodBranch coverage Cyclomatic complexity NPath complexity Sequence coverage
.ctor(...)100%11100%
ExecuteAsync()100%22100%
Reset()100%11100%
OnSuccess()100%22100%
OnFailure()100%66100%
CheckHalfOpenTransition()83.33%66100%

File(s)

/home/runner/work/Intentum/Intentum/src/Intentum.Runtime/Resilience/CircuitBreaker/MemoryCircuitBreaker.cs

#LineLine coverage
 1using Intentum.Runtime.Resilience.Exceptions;
 2
 3namespace Intentum.Runtime.Resilience.CircuitBreaker;
 4
 5public sealed class MemoryCircuitBreaker : ICircuitBreaker
 6{
 7    private readonly CircuitBreakerOptions _options;
 88    private readonly object _lock = new();
 89    private CircuitState _state = CircuitState.Closed;
 10    private int _failureCount;
 11    private int _halfOpenAttempts;
 12    private DateTime _lastFailureTime;
 13
 814    public MemoryCircuitBreaker(CircuitBreakerOptions options)
 815    {
 816        _options = options;
 817    }
 18
 19    public CircuitState State
 20    {
 21        get
 622        {
 623            CheckHalfOpenTransition();
 624            return _state;
 625        }
 26    }
 27
 28    public async Task<T> ExecuteAsync<T>(Func<Task<T>> operation)
 1129    {
 1130        CheckHalfOpenTransition();
 31
 1132        if (_state == CircuitState.Open)
 133            throw new CircuitBreakerOpenException();
 34
 35        try
 1036        {
 1037            var result = await operation();
 238            OnSuccess();
 239            return result;
 40        }
 841        catch
 842        {
 843            OnFailure();
 844            throw;
 45        }
 246    }
 47
 48    public void Reset()
 149    {
 150        lock (_lock)
 151        {
 152            _state = CircuitState.Closed;
 153            _failureCount = 0;
 154        }
 155    }
 56
 57    private void OnSuccess()
 258    {
 259        lock (_lock)
 260        {
 261            if (_state == CircuitState.HalfOpen)
 162            {
 163                _state = CircuitState.Closed;
 164                _failureCount = 0;
 165                _halfOpenAttempts = 0;
 166            }
 267        }
 268    }
 69
 70    private void OnFailure()
 871    {
 872        lock (_lock)
 873        {
 874            _failureCount++;
 875            _lastFailureTime = DateTime.UtcNow;
 76
 877            if (_state == CircuitState.HalfOpen)
 178            {
 179                _halfOpenAttempts++;
 180                if (_halfOpenAttempts >= _options.HalfOpenMaxAttempts)
 181                    _state = CircuitState.Open;
 182            }
 783            else if (_failureCount >= _options.FailureThreshold)
 684            {
 685                _state = CircuitState.Open;
 686            }
 887        }
 888    }
 89
 90    private void CheckHalfOpenTransition()
 1791    {
 2892        if (_state != CircuitState.Open) return;
 93
 694        lock (_lock)
 695        {
 696            if (_state == CircuitState.Open &&
 697                DateTime.UtcNow - _lastFailureTime >= _options.DurationOfBreak)
 398            {
 399                _state = CircuitState.HalfOpen;
 3100            }
 6101        }
 17102    }
 103}