bound /api/state container rescan so introspection survives a saturated build backend

This commit is contained in:
damocles 2026-06-18 21:15:29 +02:00 committed by mara
commit 69682a6afa

View file

@ -501,7 +501,28 @@ async fn api_state(headers: HeaderMap, State(state): State<AppState>) -> axum::J
// produced; live clients converge via the matching
// `ContainerStateChanged` / `ContainerRemoved` events the rescan
// emits.
state.coord.rescan_containers_and_emit().await;
//
// Bound the rescan: it shells out (`nixos-container list` etc.), so a
// saturated/wedged build backend — e.g. hive-c0re mid-startup-sweep
// hammering slow `nixos-container update` subprocesses — can stall it
// long enough that `/api/state` hangs for the whole request (the
// ~minute-long /state reported in the field). On timeout we skip the
// fresh rescan and serve the last cached snapshot instead; live
// clients still converge via the SSE events a later successful rescan
// emits, and the next /state call retries the refresh. Introspection
// stays responsive regardless of the build backend's health.
if tokio::time::timeout(
std::time::Duration::from_secs(3),
state.coord.rescan_containers_and_emit(),
)
.await
.is_err()
{
tracing::warn!(
"api_state: container rescan exceeded 3s (build backend likely saturated); \
serving last cached snapshot"
);
}
let containers = state.coord.containers_snapshot().await;
let any_stale = containers.iter().any(|c| c.needs_update);
let transient_snapshot = state.coord.transient_snapshot();