Skip to main content

TaskNode

Struct TaskNode 

Source
pub struct TaskNode { /* private fields */ }
Expand description

A node in the supervisor’s task graph.

Designed to live in static memory: every field is Sync, all constructors are const. Declared by supervisor_graph!, which emits one per managed task along with the Graph (GRAPH) that Supervisor::new consumes.

Split in two on purpose. The handle’s atomics force this static into RAM — and would force everything beside them into RAM too — so the node holds only its live state plus one reference to its NodeCfg, the immutable half (name, mode, spawn fn, gates, budgets, coupling tables), which has no interior mutability and therefore stays in flash. Same lesson as the graph’s Topology, one level down: keep the constant data out of reach of the atomics.

Implementations§

Source§

impl TaskNode

Source

pub fn veto<const N: usize>(&self, s: Sig<VetoGate<N>>) -> Option<Veto<N>>

This node’s handle on the gate s, bound to the contributor slot the graph assigned its writes: [.. veto] entry. None (and a warning) when no such entry names the gate — a body reaching a gate its declaration never claimed a slot in.

Source§

impl TaskNode

Source

pub fn put<T: Sink + Sync>(&self, s: Sig<T>, v: T::Item)

Write v into the signal s.

Source

pub fn beat_put<T: Sink + Sync>(&self, s: Sig<T>, v: T::Item)

Write v into s and record a heartbeat.

Source

pub fn get<T: Source + Sync>(&self, s: Sig<T>) -> T::Item

Read and return a snapshot of the signal s.

Source

pub fn writer<T: Sync + ?Sized>(&self, s: Sig<T>) -> &'static T

Borrow the signal target for a direct write, bypassing the Sink trait.

Source

pub fn beat_writer<T: Sync + ?Sized>(&self, s: Sig<T>) -> &'static T

writer that is also the node’s sign of life — the

Source

pub fn reader<T: Sync + ?Sized>(&self, s: Sig<T>) -> &'static T

Hand the signal back for a read — the wiring point for consuming reads, which need per-consumer handle state no shared static can carry: node.reader(&ESTIMATE).receiver(). A pass-through, like get.

Source§

impl TaskNode

Source

pub async fn retire<T: Sync>( &'static self, s: Sig<Backed<T>>, cooldown: Duration, )

Wait until no reader has held s for cooldown, then clear readiness and, with control, request deactivation. If a reader arrives during the wait, restart the cooldown. The readiness handshake keeps the stop race-free: readers admitted after clear_ready wait for the next activation instead of reading a producer that is shutting down.

Source§

impl TaskNode

Source

pub async fn open<T: Gated + Sync + ?Sized>( &'static self, s: Sig<T>, ) -> T::Handle

Open a gated signal: admit this node, wait for the producer, then return the gate’s handle. For Backed this is an Open guard; dropping it lets the producer retire.

Source§

impl TaskNode

Source

pub fn lease<T: Sync>(&self, s: Sig<Leased<T>>) -> Option<Lease<T>>

Acquire a lease on a Sig<Leased<T>> signal.

Source§

impl TaskNode

Source

pub const fn new(cfg: &'static NodeCfg, disabled_at_boot: bool) -> Self

A node over its flash-resident NodeCfg. disabled_at_boot seeds the node’s disabled flag so a control-started node (e.g. an OTA task) can be declared down and started later via a control op. const; supervisor_graph! emits the config static and this call together.

Source

pub const fn name(&self) -> &'static str

Human-readable name. Used in defmt logs and panic messages.

Source

pub const fn mode(&self) -> Mode

Lifecycle policy. See Mode.

Source

pub const fn ready_on_write(&self) -> bool

Does this node let an observed write assert its readiness?

Source

pub const fn slot_timeout(&self) -> Duration

This node’s pre-spawn gate-wait bound (see with_slot_timeout). The whole-graph waves budget all of a node’s gates together, from when its in-pass deps resolve; the single-node path (start_node) gives each gate — executor slot, each resources: slot, each ready dep — the full budget.

Source

pub const fn ack_timeout(&self) -> Duration

How long a stop waits for this node’s shutdown ack before faulting it (see with_ack_timeout). Both stop paths honor it: the single-node wait, and the whole-graph wave, where each node’s window runs from the moment it is signalled.

Source

pub const fn ready_deps(&self) -> &'static [&'static TaskNode]

The deps whose readiness bring-up awaits before spawning this node (the ready-marked subset of deps:). Empty when none are marked.

Source

pub const fn beat_timeout(&self) -> Option<Duration>

This node’s liveness budget, or None when it is not policed (see with_beat_timeout).

Source

pub const fn beat_window(&self) -> u8

Consecutive stale sweeps required before the monitor reports this node (see with_beat_window).

Source

pub const fn reads(&self) -> &'static [&'static [Coupling]]

The signals this node declares it consumes (reads:).

Source

pub const fn writes(&self) -> &'static [&'static [Coupling]]

The signals this node declares it produces (writes:).

Source

pub const fn bound_deps(&self) -> &'static [&'static TaskNode]

The bound-marked subset of deps: (see with_bound_deps).

Source

pub const fn graph(&self) -> &'static [Option<&'static TaskNode>]

The node slots of the graph this node belongs to, #[cfg]-ed-out slots included as None — the same table Graph::nodes exposes, reached from a node rather than from the graph static. Empty for a node no graph declared.

Source

pub fn is_bound_stopped(&self) -> bool

True while this node is down because a bound provider withdrew readiness — as opposed to is_disabled, which means somebody stopped it on purpose. The distinction matters: a bound stop must lift by itself when the provider recovers, and a manual stop must not.

Source

pub fn shutdown_requested(&self) -> bool

True if the supervisor has asked this node to shut down. A Fault::Wedge hides the request until cleared.

Source

pub async fn wait_shutdown(&self)

Wait until the supervisor asks this node to shut down. A Fault::Wedge keeps this pending until cleared.

Source

pub fn ack_dropped(&self)

Acknowledge that this node’s instance has dropped and notify waiters. A Fault::Wedge swallows the ack until cleared.

Source

pub fn release_claims(&self)

Give back every divisible share this node holds (see NodeCfg::with_claims). Idempotent: releasing an empty slot stores zero.

Source

pub fn mark_exited(&self)

Mark the task as completed and acknowledge its drop. A wedge hides this until cleared.

Source

pub fn fault(&self) -> Fault

Current injected fault, or None if healthy.

Source

pub fn inject(&self, fault: Fault) -> Result<(), InjectError>

Inject a fault, or clear it with Fault::None. Stall, crash and hog need a task: shell; wedge works on any node.

Source

pub fn clear_fault(&self)

Clear the injected fault and replay anything it withheld.

Source

pub fn has_exited(&self) -> bool

Return true if the node has been marked as exited.

Source

pub fn set_ready(&self)

Assert this node’s readiness and wake dependents waiting on it.

Source

pub fn clear_ready(&self)

Clear this node’s readiness.

Source

pub fn is_ready(&self) -> bool

Return whether this node is currently ready.

Source

pub async fn wait_ready(&self)

Wait until this node becomes ready.

Source

pub fn beat(&self)

Record a liveness beat for this node.

Source

pub fn poll_observed_writes(&self) -> bool

Return whether any observed beat coupling has changed since last call.

Source

pub fn report_status(&self, status: &'static str)

Report a status string for this node.

Source

pub fn status(&self) -> Option<&'static str>

The node’s current self-description, if it reported one this activation.

Source

pub fn ticks_since_beat(&self) -> u32

Ticks since the last beat — where, with dataflow, a write through the node’s verbs since the previous call counts as one, granted here (wrapping arithmetic; correct for gaps under the u32 tick wrap, ~71 min at 1 MHz — far above any sane max_age).

Source

pub fn is_stale(&self, max_age: Duration) -> bool

True when the node is running but hasn’t beaten within max_age — the alive-but-stalled detector (a task hogging nothing, parked on an await that will never complete). Not-running nodes are never stale: a stopped or completed node is down, which is_running/has_exited already report. Complements the trace stall watermark, which catches the opposite failure (a poll that never yields).

Source

pub fn epoch(&self) -> u32

This node’s activation generation: 0 before the first spawn, then incremented on every transition into running — a fresh spawn, a pool grow, a respawn_terminate, or a Pause node’s resume.

The dependent-side answer to “my provider was restarted underneath me”. deps: gates a spawn once; nothing re-gates a node that is already running when one of its providers cycles. A consumer holding derived state (a filter, a session, a cached handle) samples this once and compares it each iteration — one relaxed load, cheap enough for a 1 kHz loop:

let mut seen = PROVIDER.epoch();
loop {
    let sample = INPUT.wait().await;
    let now = PROVIDER.epoch();
    if now != seen {
        seen = now;
        filter.reset();   // the provider is a new instance; derived state is stale
    }
    // ...
}
Source

pub async fn wait_epoch_change(&self, seen: u32) -> u32

Wait until the node’s epoch counter differs from seen.

Source

pub async fn wait_resume(&self)

Wait until the supervisor signals this Pause-mode node to resume.

Source

pub fn run_cancellable<F: Future>( &self, fut: F, ) -> impl Future<Output = Result<F::Output, Aborted>>

Run fut until it completes or the node is stopped, returning Aborted on stop.

Source

pub fn run_cancellable_acked<F: Future>( &self, fut: F, ) -> impl Future<Output = Result<F::Output, Aborted>>

Like run_cancellable, but also acks the stop handshake.

Source

pub fn run_pausable<F: Future>( &self, fut: F, ) -> impl Future<Output = Result<F::Output, Resumed>>

Run fut until it completes or the node is paused, returning Resumed on pause.

Source

pub async fn run_pausable_loop(&self, body: impl AsyncFnMut()) -> !

Run body in a run_pausable loop forever, surviving pause/resume cycles.

Source

pub fn mark_busy(&self)

Mark this node as busy, requesting pool scale-out if one is configured.

Source

pub fn mark_idle(&self)

Mark this node as idle, requesting pool scale-in if one is configured.

Source

pub fn is_busy(&self) -> bool

Return true if the node is currently marked busy.

Source

pub fn is_running(&self) -> bool

Return true if the node has a running instance.

Source

pub fn is_disabled(&self) -> bool

Return true if the node has been manually disabled.

Source

pub fn is_collateral(&self) -> bool

Return true if the node is held stopped as a dependent of a deactivated node.

Source

pub fn set_detached(&self, detached: bool)

Set whether this node is detached from automatic lifecycle management.

Source

pub fn is_detached(&self) -> bool

Return true if the node is detached from automatic lifecycle management.

Source

pub fn set_task_id(&self, id: u32)

Record the executor task id for this node instance.

Source

pub fn adopt<S>(&self, token: &SpawnToken<S>)

Adopt a spawn token’s task id (and name, if enabled) for tracing.

Source

pub async fn adopt_current(&self)

Adopt the current task’s id for tracing.

Source

pub fn stamp_name<S>(&self, token: &SpawnToken<S>)

Set the spawn token’s task name to this node’s configured name.

Source

pub fn task_id(&self) -> u32

Return the id of the task currently adopted by this node.

Source

pub fn exec_ticks(&self) -> u32

Return the accumulated execution tick count for this node.

Source

pub fn poll_count(&self) -> u32

Return the number of poll cycles recorded for this node.

Source

pub fn max_poll_ticks(&self) -> u32

Return the longest single-poll tick count recorded for this node.

Source

pub fn set_disabled(&self, disabled: bool)

Manually disable or re-enable this node.

Trait Implementations§

Source§

impl Debug for TaskNode

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> CouplingPoint for T
where T: Sync + ?Sized,

Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = !

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, !>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.