Circuit Breaker Pattern in C#

Introduction

Robustness and resilience are crucial aspects of a well-designed software system. The Circuit Breaker Pattern serves as a reliable protector that ensures the stability and dependability of applications, especially when dealing with unpredictable or failing services. This pattern, which originated from the field of electrical engineering, has been adapted into software development as a means of handling faults and preventing cascading failures.

Circuit Breaker Pattern in C#

The Circuit Breaker Pattern operates akin to its namesake in an electrical circuit: it monitors the flow of requests or calls to an external service. When the system detects a certain threshold of failures, it "opens" the circuit, preventing further calls to the troubled service. This temporary halt allows the system to recuperate, thereby avoiding additional stress on the failing service and preventing potential system-wide failures.

Implementation in C#

State: The circuit breaker can exist in three primary states:

  • Closed: In this state, requests to the external service are allowed to pass through.
  • Open: The circuit breaker has detected a fault and prevents further requests to the service for a specified duration.
  • Half-Open: After a defined time period, the circuit breaker transitions to this state, allowing a limited number of requests to determine if the service has recovered.

Tripping Thresholds: These thresholds define the conditions for the circuit breaker to trip from a closed to an open state. For instance, if a certain number of consecutive failures or a specific error rate occurs, the circuit breaker will trip.

Sample Implementation

In C#, implementing a basic version of the Circuit Breaker Pattern can be achieved through various means. One such example utilizes a class structure.

public class CircuitBreaker
{
    private int _failureThreshold;
    private int _resetTimeout;
    private DateTime _lastFailureTime;
    private bool _isCircuitOpen;

    public CircuitBreaker(int failureThreshold, int resetTimeout)
    {
        _failureThreshold = failureThreshold;
        _resetTimeout = resetTimeout;
        _lastFailureTime = DateTime.MinValue;
        _isCircuitOpen = false;
    }

    public void Execute(Action action)
    {
        if (_isCircuitOpen && _lastFailureTime.AddSeconds(_resetTimeout) < DateTime.Now)
        {
            _isCircuitOpen = false;
        }

        if (_isCircuitOpen)
        {
            throw new CircuitBreakerOpenException("Circuit breaker is open");
        }

        try
        {
            action();
        }
        catch (Exception)
        {
            _lastFailureTime = DateTime.Now;
            if (++_failureThreshold >= _failureThreshold)
            {
                _isCircuitOpen = true;
            }
            throw;
        }
    }
}

Conclusion

The Circuit Breaker Pattern offers a robust strategy to enhance the resilience of software systems, preventing catastrophic failures and enabling graceful degradation. While this basic implementation demonstrates its functionality, numerous libraries and frameworks in C# provide more sophisticated and battle-tested versions of this pattern, catering to various use cases and scenarios.


Similar Articles