dashboard: show meta-update progress in the META INPUTS panel

post_meta_update returns 200 immediately and runs the nix flake
update + agent-rebuild ripple in a background task, so the META
INPUTS panel looked idle for the whole multi-minute window (#259).

Track in-flight runs with a Coordinator atomic counter, exposed via
an RAII MetaUpdateGuard held across run_meta_update. Surface it as
the meta_update_running snapshot field plus a MetaUpdateRunning SSE
event (flipped only when the count crosses 0, so concurrent runs
flip the flag once). The panel shows a pulsing in-progress banner
and disables the update button while a run is active.
This commit is contained in:
iris 2026-05-22 21:54:28 +02:00
parent 20d2b48fe5
commit 2f1b846baf
6 changed files with 119 additions and 3 deletions

View file

@ -206,6 +206,12 @@ struct StateSnapshot {
/// Inputs in `meta/flake.lock` the operator can selectively
/// `nix flake update`. Hyperhive first, then `agent-<n>` rows.
meta_inputs: Vec<MetaInputView>,
/// True while a dashboard-triggered `meta-update` (flake lock bump +
/// agent rebuild ripple) is running in the background. Lets a
/// client that cold-loads mid-update render the META INPUTS panel's
/// disabled "updating…" state; live transitions arrive via the
/// `MetaUpdateRunning` event (issue #259).
meta_update_running: bool,
/// Whether the hive-forge container is up. When true the dashboard
/// links each container's config + each approval's commit into the
/// forge's `agent-configs` repos.
@ -395,6 +401,7 @@ async fn api_state(headers: HeaderMap, State(state): State<AppState>) -> axum::J
approvals,
approval_history,
meta_inputs: read_meta_inputs(),
meta_update_running: state.coord.meta_update_in_progress(),
questions,
question_history,
tombstones,
@ -1495,6 +1502,10 @@ async fn post_meta_update(
/// operator and manager get the same feedback they'd see from an
/// auto-update / manual dashboard rebuild.
async fn run_meta_update(coord: &Arc<crate::coordinator::Coordinator>, inputs: &[String]) {
// Held for the whole run (incl. the early `return` on lock failure):
// emits `MetaUpdateRunning { running: true }` now and `false` on
// drop so the META INPUTS panel shows progress (issue #259).
let _progress = coord.meta_update_guard();
tracing::info!(?inputs, "meta-update: starting");
if let Err(e) = crate::meta::lock_update(inputs).await {
tracing::warn!(error = ?e, "meta-update: lock_update failed");