bb_runtime/engine/pending_async.rs
1//! `PendingAsync` + `ExecutionState` - engine's async-suspension
2//! bookkeeping + execution liveness
3//! tracking per §5.3.
4
5use crate::ids::{ExecId, NodeSiteId, OpRef};
6
7/// Bookkeeping for an Op suspended on a `CommandId` per
8/// `docs/ENGINE.md` §9.1. Stored in `Engine.pending_async`,
9/// keyed by `CommandId`.
10pub struct PendingAsync {
11 /// The Op that's suspended.
12 pub op_ref: OpRef,
13 /// The execution this suspension belongs to.
14 pub exec_id: ExecId,
15 /// Output sites the Op declared. Populated when the CommandId
16 /// completes with values.
17 pub output_sites: Vec<NodeSiteId>,
18 /// Absolute deadline (`scheduler.now_ns()` clock) past which
19 /// the suspension expires. `None` means "no engine-side
20 /// deadline" - the Op runs until the transport reports
21 /// completion or failure. Phase 5 of the poll cycle scans
22 /// pending suspensions each tick and fails any whose deadline
23 /// has passed via the existing `OpFailed` path.
24 pub deadline_ns: Option<u64>,
25}
26
27/// Per-execution liveness tracker
28/// Stored in `Engine.execution_state`, keyed by `ExecId`. /// minimum-viable: just the output counter for GC bookkeeping;
29/// may extend.
30#[derive(Default)]
31pub struct ExecutionState {
32 /// How many output sites this execution has filled.
33 pub outputs_written: u32,
34}