Per-environment GenServer circuit breaker.
Implements the classic three-state circuit breaker pattern:
- Closed — normal operation, all requests pass through
- Open — fast-fail mode; all requests rejected without hitting Plaid
- Half-open — recovery probe; one request allowed to test the service
State transitions
Closed ──[N failures]--> Open ──[reset_ms elapsed]--> Half-open
│
Closed <──[success]──────────────────────────┤
Open <──[failure]──────────────────────────┘Per-environment isolation
Each Plaid environment (sandbox / development / production) gets its
own circuit breaker, supervised under CircuitBreakerSupervisor.
An institution outage in sandbox never affects production.
Plaid-specific triggers
The circuit opens on INSTITUTION_DOWN, INSTITUTION_NOT_RESPONDING,
PLANNED_MAINTENANCE, and consecutive 5xx errors. It does NOT open
on RATE_LIMIT_EXCEEDED (those are handled by backoff in the client)
or on ITEM_LOGIN_REQUIRED (user action errors).
Summary
Functions
Checks whether a request is allowed.
Returns a specification to start this module under a supervisor.
Records a failure response. Increments failure count and may open the circuit if the threshold is breached.
Records a successful response. Resets failure count; transitions half-open → closed after enough successes.
Manually resets the circuit breaker to closed state. Use this if you've confirmed the service is healthy.
Returns the current state of the circuit breaker.
Types
Functions
@spec check(atom(), PlaidEx.Config.t()) :: :ok | {:error, :circuit_open}
Checks whether a request is allowed.
Returns :ok if the circuit is closed or half-open,
{:error, :circuit_open} if the circuit is open.
Returns a specification to start this module under a supervisor.
See Supervisor.
@spec record_failure(atom(), PlaidEx.Error.t()) :: :ok
Records a failure response. Increments failure count and may open the circuit if the threshold is breached.
@spec record_success(atom()) :: :ok
Records a successful response. Resets failure count; transitions half-open → closed after enough successes.
@spec reset(atom()) :: :ok
Manually resets the circuit breaker to closed state. Use this if you've confirmed the service is healthy.
@spec start_link({atom(), PlaidEx.Config.t()}) :: GenServer.on_start()
@spec status(atom()) :: state_name()
Returns the current state of the circuit breaker.