# `Raxol.Core.Runtime.Backpressure`
[🔗](https://github.com/DROOdotFOO/raxol/blob/v2.8.0/lib/raxol/core/runtime/backpressure.ex#L1)

Adaptive backpressure for hot-path `GenServer.cast`.

Probes the target mailbox depth via `Process.info(pid, :message_queue_len)`
and switches behaviour when the queue crosses a watermark. See
`docs/adr/0013-event-dispatch-backpressure.md` for the design rationale.

## Policies

  * `:call_when_full` -- escalate to a synchronous `GenServer.call/3`,
    applying backpressure to the caller. Use when message loss is
    unacceptable (input dispatch, test determinism).
  * `:drop_when_full` -- drop the message and return
    `{:dropped, :overflow}`. Use when the consumer naturally recovers
    from drops (frame batching, idempotent updates).
  * `:fail_when_full` -- same return shape as `:drop_when_full`; the
    `policy` field in telemetry metadata distinguishes "expected drop"
    from "explicit failure" for handler-side severity routing.

## Telemetry

Emits `[:raxol, :runtime, :backpressure]` on every invocation.

  * Measurements: `%{queue_len: non_neg_integer()}`
  * Metadata: `%{label, policy, decision, target}` where `decision` is
    one of `:cast`, `:call`, `:drop`, `:no_proc`.

## Examples

    Backpressure.cast(MyDispatcher, {:dispatch, event},
      label: :dispatcher_input,
      policy: :call_when_full,
      watermark: 1_000
    )

# `decision`

```elixir
@type decision() :: :cast | :call | :drop | :no_proc
```

# `policy`

```elixir
@type policy() :: :call_when_full | :drop_when_full | :fail_when_full
```

# `result`

```elixir
@type result() :: :ok | {:dropped, :overflow | :no_proc}
```

# `cast`

```elixir
@spec cast(GenServer.server(), term(), keyword()) :: result()
```

Send `message` to `target` with backpressure-aware delivery.

Required opts: `:label` (atom for telemetry), `:policy`.
Optional opts: `:watermark` (default 1000),
`:timeout` (default 5000, only used for `:call_when_full`).

---

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