docs: add coordinator.md, move rebuild-queue prose from code (#715)

This commit is contained in:
damocles 2026-06-01 10:07:51 +02:00 committed by mara
commit 64f11a862d
3 changed files with 129 additions and 54 deletions

View file

@ -1,53 +1,8 @@
//! Global rebuild queue.
//!
//! Every long-running container/meta operation (rebuild, meta-update,
//! first-spawn) goes through this queue. A single background worker
//! drains it in FIFO order so we never overlap two `nixos-container
//! update` runs on the same agent and never start a fresh agent rebuild
//! while a meta-update's lock bump is mid-flight.
//!
//! ## Why one queue
//!
//! Before this module landed, four independent call paths could fire
//! `auto_update::rebuild_agent` concurrently:
//! - dashboard manual rebuild button
//! - `update-all` / `meta-update` cascade
//! - approval handler (apply-commit / spawn)
//! - startup auto-update sweep
//!
//! Nothing serialised them. nix-daemon serialises the actual store
//! ops, but the rest of `rebuild_agent` (token sync, kick, rescan,
//! lock-bump emit) interleaved unpredictably. The single-worker queue
//! gives operators a visible, ordered runway and lets the UI render
//! "what's about to happen" instead of "something might be happening
//! somewhere."
//!
//! ## Scope
//!
//! In-queue kinds:
//! - `Rebuild` — a single-agent rebuild (covers manual / approval-driven /
//! auto-update / meta-update cascade variants — they all funnel here).
//! - `MetaUpdate` — `nix flake update` on the meta flake. The worker
//! runs the lock bump itself, then enqueues a cascade of `Rebuild`
//! entries with `parent_id` set to the meta-update's id.
//! - `Spawn` — first-deploy of an agent (approval-driven). Same
//! serialisation as `Rebuild` from the operator's POV.
//! - `Destroy` — for future use (`destroy --purge` does real I/O); not
//! currently routed through the queue.
//!
//! Out of scope (intentionally not queued — these are sub-second ops
//! and adding them adds visual noise without serving the "one at a
//! time" goal):
//! - `start` / `stop` / `restart`
//! - `kill`
//!
//! ## Dedup
//!
//! Enqueueing `(kind, agent)` that already has a `Queued` entry returns
//! the existing entry's id and appends the new reason as an
//! "also requested by …" line. Running entries do not dedup — a
//! re-queue during a run is legitimate (something changed since the
//! current run started).
//! Global rebuild queue — serialises all long-running container/meta
//! operations (rebuild, meta-update, first-spawn) through a single
//! background worker. Design rationale, kind taxonomy, dedup rules,
//! cascade parent tracking, and step labels:
//! `docs/coordinator.md::Rebuild queue`.
use std::collections::VecDeque;
use std::sync::Mutex;