diff --git a/hive-c0re/src/agent_sockets.rs b/hive-c0re/src/agent_sockets.rs index cbfff2fc..804a24d7 100644 --- a/hive-c0re/src/agent_sockets.rs +++ b/hive-c0re/src/agent_sockets.rs @@ -180,41 +180,6 @@ fn render(map: &BTreeMap) -> String { /// stable and inotify watchers in the gateway (or any future /// watchers) don't fire spurious reload events. Mirrors the /// `agent_ports::write` shape — keep them in lockstep. -/// Spawn the marker poll task. Periodically re-runs `write` so the -/// JSON map picks up newly-bound sockets (an agent flipping -/// `hyperhive.web.useUnixSocket = true`, rebuilding, then having its -/// harness drop a fresh `.bound` marker) without needing an explicit -/// hook on container start. `write` is idempotent (skips the -/// rename when content unchanged) so the steady-state cost is one -/// directory stat per agent per poll interval. -/// -/// Mirrors the spawn-loop shape used by `crash_watch`, -/// `reminder_scheduler`, etc. — the existing background-task -/// convention in `main.rs`. -pub fn spawn_poll(coord: std::sync::Arc) { - let _ = coord; - tokio::spawn(async move { - let mut interval = tokio::time::interval(std::time::Duration::from_secs(10)); - // First tick fires immediately; that's fine — meta::sync_agents - // also writes on boot, this just catches up the window before - // the next agent restart. - loop { - interval.tick().await; - match crate::lifecycle::agents_for_meta_listing().await { - Ok(agents) => { - let names: Vec = agents.into_iter().map(|a| a.name).collect(); - if let Err(e) = write(&names) { - tracing::debug!(error = ?e, "agent_sockets poll write failed"); - } - } - Err(e) => { - tracing::debug!(error = ?e, "agent_sockets poll: failed to list agents"); - } - } - } - }); -} - pub fn write(names: &[String]) -> Result<()> { let map = build_map(names); let body = render(&map); @@ -239,6 +204,40 @@ pub fn write(names: &[String]) -> Result<()> { Ok(()) } +/// Spawn the marker poll task. Periodically re-runs `write` so the +/// JSON map picks up newly-bound sockets (an agent flipping +/// `hyperhive.web.useUnixSocket = true`, rebuilding, then having its +/// harness drop a fresh `.bound` marker) without needing an explicit +/// hook on container start. `write` is idempotent (skips the rename +/// when content unchanged) so the steady-state cost is one directory +/// stat per agent per poll interval. +/// +/// Mirrors the spawn-loop shape used by `crash_watch`, +/// `reminder_scheduler`, etc. — the existing background-task +/// convention in `main.rs`. +pub fn spawn_poll() { + tokio::spawn(async move { + let mut interval = tokio::time::interval(std::time::Duration::from_secs(10)); + // First tick fires immediately; that's fine — meta::sync_agents + // also writes on boot, this just catches up the window before + // the next agent restart. + loop { + interval.tick().await; + match crate::lifecycle::agents_for_meta_listing().await { + Ok(agents) => { + let names: Vec = agents.into_iter().map(|a| a.name).collect(); + if let Err(e) = write(&names) { + tracing::debug!(error = ?e, "agent_sockets poll write failed"); + } + } + Err(e) => { + tracing::debug!(error = ?e, "agent_sockets poll: failed to list agents"); + } + } + } + }); +} + #[cfg(test)] mod tests { use super::*; diff --git a/hive-c0re/src/main.rs b/hive-c0re/src/main.rs index 757f4c33..66caf04f 100644 --- a/hive-c0re/src/main.rs +++ b/hive-c0re/src/main.rs @@ -261,7 +261,7 @@ async fn cmd_serve( // idempotent so steady-state cost is one stat per agent per // tick. closes atlas's #813 concern that agents in the JSON // would 502 the gateway until they actually opt in. - agent_sockets::spawn_poll(coord.clone()); + agent_sockets::spawn_poll(); // Reminder scheduler: drains due reminders + handles // file_path payload persistence. See reminder_scheduler.rs. reminder_scheduler::spawn(coord.clone());