Statifier.Session.Inbox (Statifier v2.0.0)

Copy Markdown View Source

The waiting external events, plus Appendix D's isCancelEvent check.

ADR-0002 mechanical deviation, ADR-0003: Appendix D's mainEventLoop owns both queues and blocks on externalQueue.dequeue(), checking isCancelEvent/1 on what it dequeues. Statifier.MachineState owns only the internal queue, so the waiting external events and the cancel check live here, in the driver. The semantics of processing one external event are unchanged; only the storage of the waiting ones moves.

Appendix D's isCancelEvent is described by spec 6.4 as platform specific ("here we assume it's a special event we receive"). This platform makes the cancel a distinct queue entry rather than a reserved event name, so no document can raise one by writing that name, and cancel_event?/1 is a structural match.

Summary

Types

One waiting entry: an external event, an external event one of this session's own invocations delivered, or the cancel marker.

t()

Functions

Appendix D's isCancelEvent/1: true only for the cancel marker itself.

Appends the cancel marker to the back of the inbox.

Appends event to the back of the inbox, wrapped as an :event entry.

Appends event as an entry originating from this session's own invocation invoke_id - the child-to-parent direction only (<send target="#_parent"> and done.invoke.<invokeid>). Everything else, autoforwarded copies included, goes through enqueue_event/2.

An empty inbox.

Dequeues the front entry, mirroring Appendix D's externalQueue.dequeue(). :empty when nothing is waiting - there is no blocking wait here; the caller decides what to do while idle.

The waiting events, front to back, cancel markers dropped - the internal_events/1-shaped inspection view (Statifier.MachineState.internal_events/1). No code outside this module touches :queue directly.

The number of waiting entries, events and cancel markers both.

Types

entry()

@type entry() ::
  {:event, Statifier.Event.t()}
  | {:invoked_event, String.t(), Statifier.Event.t()}
  | :cancel

One waiting entry: an external event, an external event one of this session's own invocations delivered, or the cancel marker.

{:invoked_event, invoke_id, event} is a separate kind rather than a flag on event because 6.4.3's discard is a property of where the entry came from, not of the event: 6.4.2 requires an autoforwarded copy to preserve every 5.10.1 field, invokeid included, so an event forwarded down to a child still carries the sibling invocation's id in a frame where it names nothing. Keying the discard on the entry kind is what keeps a forwarded sibling event deliverable while a cancelled invocation's own queued events still drop (Statifier.Session's handle_continue(:drain, _)).

t()

@opaque t()

Functions

cancel_event?(arg1)

@spec cancel_event?(entry :: entry()) :: boolean()

Appendix D's isCancelEvent/1: true only for the cancel marker itself.

enqueue_cancel(inbox)

@spec enqueue_cancel(inbox :: t()) :: t()

Appends the cancel marker to the back of the inbox.

enqueue_event(inbox, event)

@spec enqueue_event(inbox :: t(), event :: Statifier.Event.t()) :: t()

Appends event to the back of the inbox, wrapped as an :event entry.

enqueue_invoked_event(inbox, invoke_id, event)

@spec enqueue_invoked_event(
  inbox :: t(),
  invoke_id :: String.t(),
  event :: Statifier.Event.t()
) :: t()

Appends event as an entry originating from this session's own invocation invoke_id - the child-to-parent direction only (<send target="#_parent"> and done.invoke.<invokeid>). Everything else, autoforwarded copies included, goes through enqueue_event/2.

new()

@spec new() :: t()

An empty inbox.

next(inbox)

@spec next(inbox :: t()) :: {:ok, entry(), t()} | :empty

Dequeues the front entry, mirroring Appendix D's externalQueue.dequeue(). :empty when nothing is waiting - there is no blocking wait here; the caller decides what to do while idle.

pending_events(inbox)

@spec pending_events(inbox :: t()) :: [Statifier.Event.t()]

The waiting events, front to back, cancel markers dropped - the internal_events/1-shaped inspection view (Statifier.MachineState.internal_events/1). No code outside this module touches :queue directly.

size(inbox)

@spec size(inbox :: t()) :: non_neg_integer()

The number of waiting entries, events and cancel markers both.