# `PushX.CircuitBreaker`
[🔗](https://github.com/cignosystems/pushx/blob/v0.11.0/lib/push_x/circuit_breaker.ex#L1)

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

# `provider`

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

# `state`

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

# `allow?`

```elixir
@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`

Returns a specification to start this module under a supervisor.

See `Supervisor`.

# `record_failure`

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

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

Serialized through the GenServer.

# `record_success`

```elixir
@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`

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

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

# `start_link`

Starts the circuit breaker process.

# `state`

```elixir
@spec state(provider()) :: state()
```

Returns the current circuit breaker state for a provider.

---

*Consult [api-reference.md](api-reference.md) for complete listing*
