pub struct StreamBlock {
pub chunk_type: String,
pub on_chunk: Option<StepNode>,
pub on_complete: Option<StepNode>,
pub on_error: Option<StepNode>,
pub body: Vec<FlowStep>,
pub loc: Loc,
}Expand description
v1.29.0 / v2.67.0 / v2.83.0 — stream<T> { on_chunk … on_complete … }.
The body used to NOT EXIST. parse_block_step — shared with deliberate,
consensus and (pre-retraction) transact — called skip_braced_block()
and threw the block’s contents away at PARSE time. The handler was not a
no-op because someone forgot to implement it; it was a no-op because the
body never reached the AST for anything to execute. Four advertised
primitives died in that one function.
v2.83.0 — and v2.67.0 closed that with the WRONG SHAPE. It gave the block a
body: Vec<FlowStep>, which no published block and no paper writes. The
specified surface — the design plan section 3.7, whose D8
promises “backward compat for stream<τ> 100%, cero cambios en .axon
source files de adopters” — is stream<T> { on_chunk: B₁ on_complete: B₂ },
and README block 15 publishes exactly that. Measured before this landed:
- at FLOW level the published body was a hard parse error
(
Unexpected token in flow body: 'on_chunk'); - in a STEP body the whole block was silently discarded by
skip_flow_step_structural, so block 15’sstep Streamreached the dispatcher withpix_ops=0,ask="",output=""— an EMPTY step, whoseStream.outputthe next step then reasoned over.
So v2.67.0’s attestation was the v2.83.0 reason defect one more time: a real
engine behind a grammar no adopter could write. body is KEPT (it parses, it
lowers, it runs, and removing it would break any program written against
v2.67.0), but it is no longer the primitive’s published face.
Fields§
§chunk_type: StringThe <T> in stream<T> — the CHUNK type. Empty when the block is
written without one.
It used to be discarded silently: parse_stream_block’s “tolerate the
pre-111 form” loop advanced to the first {, eating <QuoteData> on the
way. A type parameter consumed by nothing is the v2.67.0 defect, so it is
captured here and type-checked at the handler boundary.
on_chunk: Option<StepNode>on_chunk: { … } — run ONCE PER CHUNK, with the chunk bound under
chunk. None when the handler is absent.
It is a StepNode, not a Vec<FlowStep>, because the published arm
body is a STEP body and not a flow body: block 15 writes
on_chunk: { probe chunk for […] output: QuoteSnapshot }, and output:
is a step field that has no flow-level position at all. Sharing the shape
means the arm reuses run_step — the design decision’s “one concept, two positions”,
so there is no second dispatch implementation to drift.
on_complete: Option<StepNode>on_complete: { … } — run ONCE, after the source closes, with the
accumulated stream bound under complete. None when absent.
on_error: Option<StepNode>v2.83.0 — on_error: { … } — run when the SOURCE fails, with the
failure bound under error.
It handles a failure of the producer, never a failure of the author’s
own handlers. If on_chunk panics its way to a dispatch error, that is a
bug in the program, and routing it here would let a broken handler
silently catch itself and report the stream as healthy. Cancellation is
not a failure either — a cancelled stream propagates as cancelled.
When present and the source fails, the step COMPLETES with this arm’s output: the author declared what to do, so the recovery is explicit rather than a swallowed error. When absent, the failure propagates.
body: Vec<FlowStep>v2.67.0’s body form: stream { <steps> }. Executed in order; each
one’s fragments are emitted on the flow’s event channel as produced.
Retained for compatibility — see the type-level note above.
loc: Loc