Skip to content

Circuit Breaker

The circuit breaker pattern blocks requests after consecutive failures to ensure system stability.

Basic Usage

from common.circuit_breaker import circuit_breaker, CircuitBreakerConfig

# Simple decorator usage
@circuit_breaker(failure_threshold=5, recovery_timeout_seconds=30.0)
def call_external_api():
    return api.get("/data")

# Detailed control with configuration object
config = CircuitBreakerConfig(
    failure_threshold=5,      # Circuit opens after 5 failures
    success_threshold=2,      # Circuit closes after 2 successes
    recovery_timeout_seconds=30.0,  # Half-open attempt after 30 seconds
)

@circuit_breaker(config=config)
async def async_call():
    return await api.async_get("/data")

Preset Configurations

from common.circuit_breaker import (
    DEFAULT_CIRCUIT_BREAKER_CONFIG,     # Default: 5 failures, 30s recovery
    SENSITIVE_CIRCUIT_BREAKER_CONFIG,   # Sensitive: 3 failures, 60s recovery
    RESILIENT_CIRCUIT_BREAKER_CONFIG,   # Resilient: 10 failures, 15s recovery
    AGGRESSIVE_CIRCUIT_BREAKER_CONFIG,  # Aggressive: 2 failures, 120s recovery
)

@circuit_breaker(config=SENSITIVE_CIRCUIT_BREAKER_CONFIG)
def critical_operation():
    return payment_service.process()

States and Behavior

State Description
CLOSED Normal operation, requests pass through
OPEN Failure threshold exceeded, requests blocked
HALF_OPEN Recovery testing, limited requests allowed
CLOSED --[failure threshold reached]--> OPEN --[recovery time elapsed]--> HALF_OPEN
   ^                                                                          |
   |                                                                          v
   +---[success threshold reached]--<--------<--------<-----------------------+
                                                                              |
   +---[failure occurred]--<--------<--------<--------------------------------+
   |
   v
  OPEN

Builder Pattern

from common.circuit_breaker import CircuitBreakerConfig

config = CircuitBreakerConfig()
config = config.with_failure_threshold(3)
config = config.with_recovery_timeout(60.0)
config = config.with_exceptions(
    exceptions=(ConnectionError, TimeoutError),
    ignored=(ValueError,),  # Exceptions to ignore
)
config = config.with_name("payment_api")

Hooks

from common.circuit_breaker import (
    circuit_breaker,
    LoggingCircuitBreakerHook,
    MetricsCircuitBreakerHook,
)

# Logging hook: automatic state change logging
logging_hook = LoggingCircuitBreakerHook()

# Metrics hook: statistics collection
metrics_hook = MetricsCircuitBreakerHook()

@circuit_breaker(failure_threshold=5, hooks=[logging_hook, metrics_hook])
def monitored_api_call():
    return external_service.call()

# Query metrics
print(metrics_hook.times_opened)    # Times circuit opened
print(metrics_hook.rejected_count)  # Rejected request count
print(metrics_hook.success_count)   # Success count

Registry Usage

from common.circuit_breaker import get_circuit_breaker, CircuitBreakerRegistry

# Get circuit breaker from global registry (or create)
cb = get_circuit_breaker("external_api", config=CircuitBreakerConfig())
result = cb.call(api_function)

# Registry management
registry = CircuitBreakerRegistry()
registry.reset_all()                   # Reset all circuits
states = registry.get_all_states()     # Query all states

Exception Handling

from common.circuit_breaker import circuit_breaker, CircuitOpenError

@circuit_breaker(failure_threshold=3)
def api_call():
    return requests.get("/data")

try:
    result = api_call()
except CircuitOpenError as e:
    print(f"Circuit open: retry possible after {e.remaining_seconds} seconds")
    # Execute fallback logic
    result = get_cached_data()

Failure Detectors

Detector Description
TypeBasedFailureDetector Exception type-based detection
CallableFailureDetector Function-based detection
CompositeFailureDetector Composite detector