# `SuperWorker.CircuitBreaker`
[🔗](https://github.com/ohhi-vn/super_worker/blob/main/lib/supervisor/circuit_breaker.ex#L1)

A simple Circuit Breaker implementation for protecting external API calls.

The circuit breaker has three states:
- `:closed` - Normal operation, requests go through
- `:open` - Requests are short-circuited (fail fast)
- `:half_open` - Testing if the service has recovered

The protected function is executed **in the caller process**, so slow calls
never block the breaker process itself and concurrent calls are not
serialized through a single process.

## Usage

    # Protect an API call
    result =
      SuperWorker.CircuitBreaker.call(:my_external_service, fn ->
        HTTPoison.get("https://api.example.com/data")
      end)

    case result do
      {:ok, response} -> # Handle success
      {:error, :circuit_open} -> # Handle circuit open
      {:error, reason} -> # Handle other errors
    end

When the call that trips the threshold fails, the real error is returned;
all subsequent calls fail fast with `{:error, :circuit_open}` until the
reset timeout elapses.

# `t`

```elixir
@type t() :: %SuperWorker.CircuitBreaker{
  failure_count: non_neg_integer(),
  failure_threshold: pos_integer(),
  half_open_max_calls: pos_integer(),
  in_flight: non_neg_integer(),
  last_failure_time: integer() | nil,
  name: atom(),
  reset_timeout: pos_integer(),
  state: :closed | :open | :half_open,
  success_count: non_neg_integer()
}
```

# `call`

```elixir
@spec call(atom(), (-&gt; {:ok, any()} | {:error, any()})) ::
  {:ok, any()} | {:error, term()}
```

Call a function protected by the circuit breaker.

The function runs in the caller process; the breaker only tracks the
outcome. Exceptions and exits inside `fun` are converted to error tuples.

# `child_spec`

Returns a specification to start this module under a supervisor.

See `Supervisor`.

# `get_state`

```elixir
@spec get_state(atom()) :: {:ok, t()} | {:error, :not_found}
```

Get the current state of the circuit breaker.

# `reset`

```elixir
@spec reset(atom()) :: :ok | {:error, :not_found}
```

Reset the circuit breaker to closed state.

# `start`

```elixir
@spec start(
  atom(),
  keyword()
) :: {:ok, pid()} | {:error, term()}
```

Start a circuit breaker for a named service.

The breaker process is linked to the caller.

---

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