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

The halt notice a session sends to the processes a send processor starts
from `c:Statifier.Send.Processor.perform/2`, such as the timer that holds
a delayed send (ADR-0069 decision 4: the processor owns the delay).

Spec 6.2 asks that a delayed send be discarded when its session
terminates before the delay elapses. A session's status can be `:done`,
`:cancelled` or `:budget_exhausted` while its process is still alive, so a
timer cannot tell from the process alone, and asking the session with a
call can time out while the session is busy. Instead, a processor hands
the process it starts to `watch/2` from inside `perform/2`, which a
`Statifier.Session` runs in its own process, and the session sends that
process

    {:statifier_halted, session, reason}

when it halts, `session` being the session's pid and `reason` one of
`:done`, `:cancelled` or `:budget_exhausted`. A process watched after the
session has halted is sent the notice at once. The session never calls
a watched process and never waits on it.

The session also keeps the watched process under the key the processor
gave it, so the processor can `take/1` the processes held under a key
(to cancel them, say), and forgets each one when it ends.

Outside a `Statifier.Session` (a host that performs instructions in its
own process), there is no session to send the notice: `watch/2` keeps
nothing and answers `:not_a_session`, and `take/1` answers `[]`.

# `notice`

```elixir
@type notice() :: {:statifier_halted, session :: pid(), reason()}
```

The message a watched process is sent when its session halts.

# `reason`

```elixir
@type reason() :: :done | :cancelled | :budget_exhausted
```

Why the session halted, as its status names it.

# `take`

```elixir
@spec take(key :: term()) :: [pid()]
```

Removes and answers every process watched under `key` in the calling
session; a taken process is sent no notice. Answers `[]` outside
a session or when none is held under `key`.

# `watch`

```elixir
@spec watch(key :: term(), pid :: pid()) :: :ok | :not_a_session
```

Watches `pid` under `key` for the session performing the current
instruction: the session sends `pid` a `t:notice/0` when it halts, or at
once when it has already halted, and keeps `pid` under `key` until `pid`
ends or is taken with `take/1`.

Call it from `c:Statifier.Send.Processor.perform/2`, which a session runs
in its own process. Answers `:not_a_session`, keeping nothing, when the
calling process is not a `Statifier.Session`.

---

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