# `ExResilience.RateLimiter`
[🔗](https://github.com/joshrotenberg/ex_resilience/blob/v0.4.0/lib/ex_resilience/rate_limiter.ex#L1)

Token bucket rate limiter implemented as a GenServer.

Maintains a bucket of tokens that refill at a steady rate. Each call
consumes one token. When the bucket is empty, calls are rejected with
`{:error, :rate_limited}`.

Uses ETS for the hot-path token check and the GenServer for refill
scheduling.

## Options

  * `:name` -- required. Registered name for this rate limiter instance.
  * `:rate` -- tokens added per interval. Default `10`.
  * `:interval` -- refill interval in ms. Default `1_000` (1 second).
  * `:max_tokens` -- bucket capacity. Default equals `:rate`.

## Examples

    iex> {:ok, _} = ExResilience.RateLimiter.start_link(name: :test_rl, rate: 5, interval: 1_000)
    iex> ExResilience.RateLimiter.call(:test_rl, fn -> :ok end)
    {:ok, :ok}

# `option`

```elixir
@type option() ::
  {:name, atom()}
  | {:rate, pos_integer()}
  | {:interval, pos_integer()}
  | {:max_tokens, pos_integer()}
```

# `result`

```elixir
@type result() :: {:ok, term()} | {:error, :rate_limited} | {:error, term()}
```

# `available_tokens`

```elixir
@spec available_tokens(atom()) :: non_neg_integer()
```

Returns the current number of available tokens.

# `call`

```elixir
@spec call(atom(), (-&gt; term())) :: result()
```

Executes `fun` if a token is available.

Returns `{:ok, result}` on success or `{:error, :rate_limited}` if
the bucket is empty.

# `child_spec`

Returns a specification to start this module under a supervisor.

See `Supervisor`.

# `start_link`

```elixir
@spec start_link([option()]) :: GenServer.on_start()
```

Starts a rate limiter process.

See module docs for available options.

---

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