feat(#2008): rebuild running agents first in the startup sweep

This commit is contained in:
damocles 2026-07-13 17:13:11 +02:00 committed by mara
commit 5857f1f871

View file

@ -226,7 +226,9 @@ pub async fn run(coord: Arc<Coordinator>) -> Result<()> {
// agent without an `agent_power` row is seeded from its observed
// state (running ⇒ Up), after which the DB is authoritative.
let mut any_stale = false;
let mut fanout: Vec<String> = Vec::new(); // stale ∧ wanted=Up → sweep rebuild
// stale ∧ wanted=Up → sweep rebuild. The bool is the agent's observed
// running state, used to order running agents first before submit.
let mut fanout: Vec<(String, bool)> = Vec::new();
let mut drifted: Vec<String> = Vec::new(); // fresh ∧ wanted≠observed → reconcile
let mut n_deferred = 0usize;
let mut n_skipped = 0usize;
@ -251,7 +253,7 @@ pub async fn run(coord: Arc<Coordinator>) -> Result<()> {
// Rebuild against the post-bump lock; the DAG's tail
// Reconcile brings the agent (back) up — covering both
// the running-stale and stopped-but-wanted-up cases.
fanout.push(name.clone());
fanout.push((name.clone(), running));
continue;
}
// Stale but wanted offline: no boot-time nix work — the
@ -273,6 +275,15 @@ pub async fn run(coord: Arc<Coordinator>) -> Result<()> {
"boot reconcile"
);
// Rebuild running agents first. All fanout entries are wanted=Up;
// among them, warm the live/serving agents onto the fresh config before the
// stopped-but-wanted-up ones so the scarce build slots hit uptime-critical
// agents first. Stable sort keeps topology order (parents before children)
// within each running/stopped group. The `drifted` reconciles aren't sorted
// — they hold no build slot and run concurrently, so their order is moot.
fanout.sort_by_key(|(_, running)| !running);
let fanout: Vec<String> = fanout.into_iter().map(|(name, _)| name).collect();
submit_boot_tree(&coord, any_stale, fanout, drifted, n_deferred, n_skipped);
Ok(())
}