# `Statifier.Session.Timers`
[🔗](https://github.com/riddler/statifier-ex/blob/v2.0.0/lib/statifier/session/timers.ex#L1)

The pending delayed-send timers, as a value.

Spec 6.3: "If multiple delayed events have this sendid, the Processor will
cancel them all" - so a send id maps to a *list* of references, in
scheduling order, not to one. A send scheduled with no id is tracked for
termination cleanup but cannot be cancelled: `<cancel>` names a sendid, and
there is none to name.

Spec 6.2 requires that a session terminating before a delay elapses discard
the message without delivering it, which is what `refs/1` exists for: the
caller cancels every reference it returns.

Nothing here calls `Process.send_after/3` or `Process.cancel_timer/1`. This
module decides which references are affected; `Statifier.Session` performs
the cancellation.

# `t`

```elixir
@opaque t()
```

# `count`

```elixir
@spec count(timers :: t()) :: non_neg_integer()
```

The number of live references.

# `forget`

```elixir
@spec forget(timers :: t(), ref :: reference()) :: t()
```

Drops a reference that has already fired: removed from the live set and
from whichever `send_id` list still names it.

# `new`

```elixir
@spec new() :: t()
```

An empty timer table.

# `put`

```elixir
@spec put(timers :: t(), send_id :: String.t() | nil, ref :: reference()) :: t()
```

Tracks `ref` as live, and appends it to `send_id`'s list when `send_id` is
not `nil` - scheduling order preserved, so a later `take/2` returns the
refs in the order they were scheduled.

# `refs`

```elixir
@spec refs(timers :: t()) :: [reference()]
```

Every live reference, `nil`-id sends included - what a terminating session cancels.

# `take`

```elixir
@spec take(timers :: t(), send_id :: String.t()) :: {[reference()], t()}
```

Removes and returns every reference under `send_id`, in scheduling order.
An unknown id returns `{[], timers}` - spec 6.3 makes that a no-op, not an
error.

---

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