Pure-functional circuit breaker for provider health tracking.
The circuit breaker maintains three states:
:closed— normal operation; requests are allowed.:open— too many failures; requests are blocked until cooldown expires.:half_open— cooldown expired; limited probe requests are allowed to test recovery.
State Transitions
:closed --(failure threshold reached)--> :open
:open --(cooldown expires)-----------> :half_open
:half_open --(probe succeeds)----------> :closed
:half_open --(probe fails)-------------> :openUsage
This module is a pure data structure with no side effects or processes. It is intended to be stored in router state per adapter.
cb = CircuitBreaker.new(failure_threshold: 3, cooldown_ms: 30_000)
cb = CircuitBreaker.record_failure(cb)
CircuitBreaker.allowed?(cb) # true (still below threshold)Configuration
failure_threshold— number of consecutive failures to trigger open state (default:5)cooldown_ms— how long to stay open before transitioning to half-open (default:30_000)half_open_max_probes— probe attempts allowed in half-open before requiring success or reopening (default:1)
Summary
Functions
Returns whether a request is allowed through the circuit breaker.
Checks and potentially transitions the state based on elapsed time.
Returns the current failure count.
Creates a new circuit breaker in :closed state.
Records a failed request.
Records a successful request.
Returns the current circuit breaker state.
Returns a map summary of the circuit breaker state.
Types
@type state() :: :closed | :open | :half_open
@type t() :: %AgentSessionManager.Routing.CircuitBreaker{ cooldown_ms: non_neg_integer(), failure_count: non_neg_integer(), failure_threshold: pos_integer(), half_open_max_probes: pos_integer(), half_open_probe_count: non_neg_integer(), opened_at_ms: integer() | nil, state: state() }
Functions
Returns whether a request is allowed through the circuit breaker.
:closed— always allowed:open— allowed only if cooldown has expired (probe):half_open— allowed if probe count is below max
Checks and potentially transitions the state based on elapsed time.
:openwith expired cooldown →:half_open- All other states → no change
@spec failure_count(t()) :: non_neg_integer()
Returns the current failure count.
Creates a new circuit breaker in :closed state.
Options
:failure_threshold— failures before opening (default:5):cooldown_ms— cooldown period in milliseconds (default:30_000):half_open_max_probes— max probes in half-open (default:1)
Records a failed request.
:closed— increments failure count; opens if threshold reached:half_open— reopens immediately:open— stays open (no-op)
Records a successful request.
:closed— resets failure count:half_open— transitions to:closed:open— resets to:closed(unexpected but safe)
Returns the current circuit breaker state.
Returns a map summary of the circuit breaker state.