From cf1f7288bffd7848cd742928ae3c7e587565b07e Mon Sep 17 00:00:00 2001 From: damocles Date: Thu, 2 Jul 2026 20:17:00 +0200 Subject: [PATCH] =?UTF-8?q?make=20agent=5Fconfig=5Fpending=20async=20?= =?UTF-8?q?=E2=80=94=20the=20sync=20git=20fork=20on=20every=20sweep=20star?= =?UTF-8?q?ved=20the=20runtime=20under=20IO=20load?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- hive-c0re/src/auto_update.rs | 13 ++++++++++--- hive-c0re/src/container_view.rs | 2 +- 2 files changed, 11 insertions(+), 4 deletions(-) diff --git a/hive-c0re/src/auto_update.rs b/hive-c0re/src/auto_update.rs index b2d9ef0a..40d81b6e 100644 --- a/hive-c0re/src/auto_update.rs +++ b/hive-c0re/src/auto_update.rs @@ -38,9 +38,15 @@ pub fn current_flake_rev(hyperhive_flake: &str) -> Option { /// deployed (i.e. the applied HEAD differs from the sha currently locked in /// meta's flake.lock). This is the semantic the dashboard `needs_update` chip /// conveys: "there is a config change ready to apply via rebuild." -#[must_use] -pub fn agent_config_pending(name: &str, deployed_sha: Option<&str>) -> bool { - let applied_head = std::process::Command::new("git") +/// +/// Async on purpose: this runs per agent inside `container_view::build_all`, +/// which fires on the ~10s dashboard sweep, every `AgentStatus` request, and +/// every `rescan_containers_and_emit` after a lifecycle step. A synchronous +/// `git` fork here blocks a tokio worker for the whole exec — under +/// nix-build disk saturation that's long enough that concurrent sweeps +/// starved the runtime and stalled the per-agent sockets. +pub async fn agent_config_pending(name: &str, deployed_sha: Option<&str>) -> bool { + let applied_head = tokio::process::Command::new("git") .args([ "-C", &format!("/var/lib/hyperhive/applied/{name}"), @@ -48,6 +54,7 @@ pub fn agent_config_pending(name: &str, deployed_sha: Option<&str>) -> bool { "HEAD", ]) .output() + .await .ok() .filter(|o| o.status.success()) .and_then(|o| String::from_utf8(o.stdout).ok()) diff --git a/hive-c0re/src/container_view.rs b/hive-c0re/src/container_view.rs index 74c41dd1..9cdda653 100644 --- a/hive-c0re/src/container_view.rs +++ b/hive-c0re/src/container_view.rs @@ -70,7 +70,7 @@ pub async fn build_all(coord: &Coordinator) -> Vec { let deployed_full = locked .get(&format!("agent-{logical}")) .map(std::string::String::as_str); - let needs_update = crate::auto_update::agent_config_pending(&logical, deployed_full); + let needs_update = crate::auto_update::agent_config_pending(&logical, deployed_full).await; let deployed_sha = deployed_full.map(|s| s[..s.len().min(12)].to_owned()); let pending_reminders = coord .broker