A logical process (spec §3, §4.2, §5). One GenServer per LP. Executes events
speculatively in {timestamp, seq} order, rolls back on stragglers and
processed-twin anti-messages, and un-sends downstream effects via anti-messages.
Queue model
Two :gb_trees keyed on {timestamp, seq}:
unprocessed— positive events awaiting processing.processed— positive events already run, retained for re-execution on rollback and for un-send accounting. Fossil collection drops the prefix below GVT.
A single watermark (lvt) is insufficient once a straggler is queued, so the
two-queue split makes "already processed" explicit and keeps same-timestamp
ordering correct via the full {ts, seq} key rather than time alone.
Anti-message matching relies on FIFO delivery
On a single node the BEAM delivers messages between any two processes in send order. A positive event is always sent before its anti-message (you cannot cancel what you have not sent), so it always arrives first. Therefore, when an anti-message arrives, its positive twin is already in this LP's queues — an anti with no live twin is stale (its twin was annihilated by an earlier anti) and is discarded. There is no "anti arrived before its twin" buffering; that case is impossible here. (Distribution, Phase 3, must revisit this.)
Mitigations baked in
- Commitment-Floor Guard (1):
rollback_to_key/3refuses to cross GVT. - Purity probe (3b): under
check_purity,handle_event/3is run twice from the same state under different global seeds and asserted equal. - Freeze/resume: supports the Coordinator's stop-the-world GVT (§6) with no sends while frozen, guaranteeing counter convergence to quiescence.
Summary
Functions
Returns a specification to start this module under a supervisor.
Functions
Returns a specification to start this module under a supervisor.
See Supervisor.