PushX.CircuitBreaker (PushX v0.11.0)

Copy Markdown View Source

Circuit breaker for push notification providers.

Tracks consecutive failures per provider and temporarily blocks requests when a provider is consistently failing, preventing resource waste on dead connections.

States

  • :closed — Normal operation, requests flow through
  • :open — Provider is failing, requests are rejected immediately
  • :half_open — Cooldown expired, one probe request is allowed through

Configuration

config :pushx,
  circuit_breaker_enabled: true,
  circuit_breaker_threshold: 5,       # consecutive failures to open
  circuit_breaker_cooldown_ms: 30_000  # ms before half_open

Usage

The circuit breaker is checked automatically in APNS.send_once/3 and FCM.send_once/3 when enabled. You can also check manually:

case PushX.CircuitBreaker.allow?(:apns) do
  :ok -> # Proceed
  {:error, :circuit_open} -> # Provider is down
end

Summary

Functions

Checks if a request is allowed for the given provider.

Returns a specification to start this module under a supervisor.

Records a failed request. Opens the circuit if the failure threshold is reached.

Records a successful request, resetting the circuit to :closed.

Resets the circuit breaker for a provider. Useful for testing or manual recovery.

Starts the circuit breaker process.

Returns the current circuit breaker state for a provider.

Types

provider()

@type provider() :: :apns | :fcm

state()

@type state() :: :closed | :open | :half_open

Functions

allow?(provider)

@spec allow?(provider()) :: :ok | {:error, :circuit_open}

Checks if a request is allowed for the given provider.

Returns :ok if the circuit is closed or half-open (probe), {:error, :circuit_open} if the circuit is open.

child_spec(init_arg)

Returns a specification to start this module under a supervisor.

See Supervisor.

record_failure(provider)

@spec record_failure(provider()) :: :ok

Records a failed request. Opens the circuit if the failure threshold is reached.

Serialized through the GenServer.

record_success(provider)

@spec record_success(provider()) :: :ok

Records a successful request, resetting the circuit to :closed.

The write is serialized through the GenServer so concurrent successes and failures cannot lose updates via ETS read-modify-write.

reset(provider)

@spec reset(provider()) :: :ok

Resets the circuit breaker for a provider. Useful for testing or manual recovery.

start_link(opts \\ [])

Starts the circuit breaker process.

state(provider)

@spec state(provider()) :: state()

Returns the current circuit breaker state for a provider.