embassy-supervisor v0.8.0
·
6 commits
to main
since this release
Six things a graph could not say about its couplings, and now can.
Ships with embassy-supervisor-macros 0.9.0 (pinned by exact version) on
embassy-supervisor-syntax 0.3.0; embassy-supervisor-tools 0.4.0 reads the
new markers.
Added
- The other half of demand-start.
Backedcounts its readers:open
hands back anOpen<T>guard (Derefto the signal,signal()for the
'staticreference),Backed::openers()is the count, and
Backed::unwatched(cooldown)resolves once it has sat at zero for the
whole cooldown — a reader arriving inside it restarts the clock.
TaskNode::retire(&SIG, cooldown)is the producer's verb: it waits that
out, withdraws readiness (so a late opener waits instead of reading a
producer on its way out, and an opener admitted just before cancels the
retirement), and withcontrolrequests its ownDeactivate. The next
openre-activates it, as before. divisibleresources (featurebudget).resources: [POWER: divisible]declares aBudget<K>the graph sizes to its holders (one slot
per node, one per pool member). Each holder's shell receives aClaimant
bound to its slot (want,grant,wait_grant_change); an allocator
provides the capacity and divides it with aBudgetPolicy—FairShare
orShrinkFastGrowSlow— onwait_change(); a change landing while
rebalanceruns re-armswait_change, so a looping allocator re-divides
at once. The supervisor releases a
holder's share when it stops, including a holder that misses its shutdown
ack; aPausepark keeps it. An unprovided budget isResourceMissing;
provides:may name one.- Distributed veto (feature
veto).writes: [crate::TRIP veto]gives a
writer one contributor slot of aVetoGate<N>: asserted while any
contributor holds it, released only once all let go. The macro numbers the
writers per gate and emits a compile-time check that the target is a
VetoGatewith a slot for each.node.veto(&TRIP)yields aVetothat
moves only its own bit; the actuator parks onwait_asserted/
wait_released. A stopped writer's bit stays asserted; release is explicit.
Undercoupling-observethe gate counts its flips, soveto observed beat
is a heartbeat. shared serialized: a compile-time rule that every holder of the slot
runs on one executor — priority ceiling by construction for a serialized
link, since embassy can neither boost a holder nor migrate a task. No
feature, no runtime cost.Stamped<T>(featurecoupling):w()stamps when a write begins and
hands the inner signal over, so a consumer can askage(),is_fresh(max)
orread_fresh(max); the token forwards to the inner signal. The read-side
half of write freshness; the README draws the line to value validity, which
stays the consumer's.- The README states the private-module recipe for gated statics and its
limit ("bypass requires going out of your way");supervisor-lint --only public-gatereports aBacked/Leased/VetoGatestatic that is not
private.
Changed
- Breaking:
TaskNode::openreturnsT::Handleinstead of&'static T—
anOpen<T>forBacked. A reader that chained a'static-taking call
onto the result (node.open(&X).await.receiver()) binds the guard first;
one that needs the'staticreference itself calls.signal().Gated
gainstype Handle: Derefandfn admit(&'static self) -> Self::Handle; a
wrapper that only waits setsHandle = &'static Self. retireandvetoare built-in write verbs of the#[dataflow]scanner.
A body that already called a node method by either name is now rewritten.ack_droppedalso wakes openers parked on the stopped producer's gate (so
they request the next start without waiting out the retry) and releases the
node'sdivisibleshares;FaultKind::ShutdownTimeoutreleases them too.- Signal entry markers (
observed,beat,veto) parse in any order;
via <expr>still qualifiesobservedand ends the entry.
Migration notes in the README, full details in the CHANGELOG.