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.
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
@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, _)).
@opaque t()
Functions
Appendix D's isCancelEvent/1: true only for the cancel marker itself.
Appends the cancel marker to the back of the inbox.
@spec enqueue_event(inbox :: t(), event :: Statifier.Event.t()) :: t()
Appends event to the back of the inbox, wrapped as an :event entry.
@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.
@spec new() :: t()
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.
@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.
@spec size(inbox :: t()) :: non_neg_integer()
The number of waiting entries, events and cancel markers both.