# `Tinkex.SamplingDispatch`
[🔗](https://github.com/North-Shore-AI/tinkex/blob/v0.4.0/lib/tinkex/sampling_dispatch.ex#L1)

Layered dispatch rate limiting for sampling requests.

Applies:
1. Global concurrency semaphore (default 400)
2. Throttled concurrency semaphore when a recent backoff was requested
3. Byte budget semaphore (5MB baseline, 20× penalty during recent backoff)

Backoff timestamps are tracked with monotonic time to match RateLimiter
behavior and keep a brief "recently throttled" window even after the
backoff has cleared.

# `snapshot`

```elixir
@type snapshot() :: %{
  concurrency: %{name: term(), limit: pos_integer()},
  throttled: %{name: term(), limit: pos_integer()},
  bytes: Tinkex.BytesSemaphore.t(),
  backoff_active?: boolean(),
  acquire_backoff: map()
}
```

# `child_spec`

Returns a specification to start this module under a supervisor.

See `Supervisor`.

# `set_backoff`

```elixir
@spec set_backoff(pid(), non_neg_integer()) :: :ok
```

Set a backoff window (in milliseconds) and mark the dispatch as recently throttled.

# `start_link`

```elixir
@spec start_link(keyword()) :: GenServer.on_start()
```

# `with_rate_limit`

```elixir
@spec with_rate_limit(pid(), non_neg_integer(), (-&gt; result)) :: result
when result: any()
```

Execute `fun` while holding layered dispatch semaphores.

---

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