core.on_event: an interrupt handler, valid inside an interrupts slot
and nowhere else (ADR-0002 decision 10).
A leaf with two config fields: the event that fires it, and the
outcome that decides what happens to the group it interrupts.
Placement, in both directions, from one tag
This type declares kinds: [:interrupt_handler] and nothing else. That
single tag is the whole placement rule:
- an
on_eventdropped into abodyslot fails, becausebodydeclares[:step]and the two sets do not intersect; - an ordinary step dropped into
interruptsfails, becauseinterruptsdeclares[:interrupt_handler]and a step is not one.
ADR-0002 decision 10 originally recorded the first direction as a special-cased validation rule the core types carry, and withdrew it at acceptance in favour of ADR-0003 decision 3's kind tags, which close both directions with one declaration on each side. There is no placement check in this module, and there is not supposed to be one: adding it back would give the editor two code paths to highlight from.
This type also never names the group types it may live inside. A host
group with an interrupts slot admits it by declaring
"interrupts" => [:interrupt_handler], and a host with a genuinely
different notion of interrupt handler mints its own kind and its own
group without touching this package.
The outcome values
ADR-0002 decision 10 fixes outcome as a :select and names no values.
Two are implemented:
outcome | Means |
|---|---|
"abandon" | leave the group and do not come back |
"resume" | handle the event and re-enter the group |
They are the minimal pair ADR-0001 decision 10's compile target needs -
transitions on the group's state, with the group's own history mode
deciding where a "resume" re-enters. A third value is a
config_schema/1 change plus a current_version/0 bump, not a document
schema change.
Summary
Functions
A compound state that waits for event and, when it arrives, raises the
interrupt-protocol event its outcome names before going final.
One example event payload, so a palette panel can show what _event.data
looks like when this handler fires.
Functions
A compound state that waits for event and, when it arrives, raises the
interrupt-protocol event its outcome names before going final.
<state id="s_INT" initial="s_INT__armed">
<state id="s_INT__armed">
<transition event="order.cancelled" target="s_INT__done">
<raise event="statifier_blocks.interrupt.abandon"/>
</transition>
</state>
<final id="s_INT__done"/>
</state>The group this handler sits in runs it as a region of a <parallel>
alongside the body, which is what keeps it live while the body works, and
transitions on both protocol events unconditionally - see
StatifierBlocks.Core.Emit. The raise is how the outcome crosses that
seam: ADR-0004 decision 4 keeps a child's config out of its parent's
context on purpose, so the group cannot read outcome and must not try.
A raised event is internal, so it is processed before any external event the queue is holding, and a nested group's handler is selected over an outer group's because SCXML prefers the transition whose source is the deepest active state.
One example event payload, so a palette panel can show what _event.data
looks like when this handler fires.
Provisional: the accepted spellings are not settled
PROVISIONAL - see ADR-0002 decision 9. The atom-keyed spelling below
comes from an amendment to that decision which has not been accepted.
Until it is, treat the shape as the intended target rather than a
settled contract. That this callback exists, and returns term(), is
settled either way.
Under statifier-ui's docs/fixture-bundles.md, events is one sample
_event.data payload per event name. The name here is an example, not
this block's configured event - fixtures/0 takes no config and could
not read one.