feat(#438): add StartupSweep queue kind — group boot-time rebuilds under a parent entry

This commit is contained in:
damocles 2026-06-01 11:50:43 +02:00 committed by mara
commit ba7e9b0ef2
4 changed files with 64 additions and 20 deletions

View file

@ -200,15 +200,12 @@ pub async fn ensure_manager(coord: &Arc<Coordinator>) -> Result<()> {
Ok(())
}
/// Rebuild every container on startup. Sequential to avoid nix-store sqlite
/// races and keep logs readable. Returns Ok even if some rebuilds failed.
/// Rebuild every container on startup. Enqueues a `StartupSweep` parent
/// entry (agent = `"hyperhive"`) followed by per-agent `Rebuild` children
/// linked via `parent_id`. The dashboard renders them nested so the operator
/// can see at a glance "boot N agents, here is each rebuild's status".
/// Returns Ok even if some rebuilds failed.
pub async fn run(coord: Arc<Coordinator>) -> Result<()> {
// Bump meta's hyperhive input up-front so per-agent rebuilds build
// against the latest base. Non-fatal on failure.
if let Err(e) = crate::meta::lock_update_hyperhive().await {
tracing::warn!(error = ?e, "auto-update: meta lock_update_hyperhive failed");
}
let containers = match lifecycle::list().await {
Ok(c) => c,
Err(e) => {
@ -217,13 +214,24 @@ pub async fn run(coord: Arc<Coordinator>) -> Result<()> {
}
};
let _current_rev = current_flake_rev(&coord.hyperhive_flake).unwrap_or_default();
// Enqueue the parent sweep entry. The worker processes it trivially
// (no-op dispatch) so it completes quickly; its purpose is to give the
// dashboard a "why" header for the per-agent child rebuilds below.
let sweep_id = coord.rebuild_queue.enqueue(
crate::rebuild_queue::QueueKind::StartupSweep,
"hyperhive".to_owned(),
crate::rebuild_queue::QueueSource::Manual,
format!("startup sweep ({} containers)", containers.len()),
None,
);
tracing::info!(
agents = containers.len(),
sweep_id,
"auto-update: queueing all on startup"
);
for container in containers {
for container in &containers {
let logical = if container == MANAGER_NAME {
Some(MANAGER_NAME.to_owned())
} else {
@ -233,9 +241,9 @@ pub async fn run(coord: Arc<Coordinator>) -> Result<()> {
coord.rebuild_queue.enqueue(
crate::rebuild_queue::QueueKind::Rebuild,
name,
crate::rebuild_queue::QueueSource::AutoUpdate,
crate::rebuild_queue::QueueSource::StartupSweep,
"startup sweep".to_owned(),
None,
Some(sweep_id),
);
}
coord.emit_rebuild_queue_snapshot();