pub async fn run(
render_state: Arc<ArcSwap<RenderState>>,
wake: CellsWake,
paint_request: Arc<Notify>,
)Expand description
Worker entry point spawned at boot. Loops forever, awaiting
the wake Notify. Each wake re-reads the latest
RenderState.cells inputs and calls recompute.
Spawn from editor_boot once Editor is constructed. Pass
clones of Editor::render_state and Editor::cells_matrix_cell
plus the wake Notify and the paint_request notifier.
§Coalescing contract (S2.5)
tokio::sync::Notify is permit-style: any notify_one()
calls that arrive while no notified().await is pending
store a single permit. The next notified().await consumes
the permit and resolves immediately. This gives us optimal
burst coalescing for free:
- Quiescent state. Worker is blocked on
notified().await. No CPU cost; no permit held. - Single wake. Publisher calls
notify_one()while the worker is parked. Worker resolves, builds, publishes, loops back, parks again. - Burst during build. Multiple
notify_one()calls arrive while the worker is mid-build. They collapse to exactly one stored permit (Notify drops subsequent calls when a permit is already present). After the current build publishes and the worker loops back, the nextnotified().awaitconsumes that single permit; one additional build runs against the LATESTrender_state.load_full()(which captures all the bursts’ inputs becauseRenderStateis published atomically viaArcSwap). - Net behaviour for a burst of N publishes during one
build. Exactly 2 builds run: the original and one tail
build that catches up to the latest state. No queue, no
intermediate states processed; the cumulative
MatrixVersiondiff drives the rebuild decision.
No explicit debounce is needed. Adding a sleep before
processing would add latency without reducing useful work —
Notify’s natural permit semantics already drop intermediate
states.
§paint_request semantics
paint_request is a shared Notify consumed by the renderer
peer. Both this worker and overlay_worker fire
notify_one() on content-changing decisions. The renderer
observes one wake per coalesced burst across both workers and
schedules a single paint — matrix + spans are read together
from the next render_state.load_full().
WorkerDecision::CacheHit leaves the matrix bit-identical so
no paint wake fires. Clear / Recomputed /
RecomputedIncremental all signal content change.