Watch
0
0
Fork
You've already forked hyperhive
0

hive-c0re: keep is_running unbounded, bound only the periodic status reads

Bounding is_running turned a hung systemctl into "not running" for
callers that record or act on the answer: the broad-stop restore set
dropped the agent, start_many could rebuild-and-restart a running
agent, reconcile could seed Offline. is_running is back to the
unbounded call it was.

The periodic workers read through the bounded running_state instead:
crash_watch (unchanged), and the swarm_agent_status publisher via the
new container_view::read_agent_status_bounded, which skips the agent
for that sweep when the unit state is unreadable. The GetAgentMeta
socket handler keeps the unbounded read_agent_status_live.
This commit is contained in:
atlas 2026-10-09 16:18:58 +02:00
commit 7214b4c22f
3 changed files with 44 additions and 14 deletions

View file

@ -4,9 +4,9 @@
//! `swarm_queue_client::agent_status`'s module doc for why hive status and
//! agent status live in separate buckets. Same direction, though: a hive
//! **offers** what it already knows about its own agents (via
//! [`crate::container_view::read_agent_status_live`], the same read
//! `GetAgentMeta` serves to the dashboard), and the swarm controller never
//! reaches down to collect it.
//! [`crate::container_view::read_agent_status_bounded`], the bounded form of
//! the read `GetAgentMeta` serves to the dashboard), and the swarm
//! controller never reaches down to collect it.
//!
//! **One publish per agent, not one document for the hive.** Each agent
//! gets its own key (`swarm_queue_client::agent_status::key`), so one
@ -39,7 +39,7 @@ const FAILURES_BEFORE_BANNER: u32 = 3;
///
/// Takes no `Coordinator` handle, unlike its sibling: this task only reads
/// agent state that already exists on disk / in the container runtime
/// (`lifecycle::agents_for_meta_listing`, `container_view::read_agent_status_live`),
/// (`lifecycle::agents_for_meta_listing`, `container_view::read_agent_status_bounded`),
/// it never touches the job queue or broker the way `swarm_status::spawn`'s
/// deploy-event listener does.
pub fn spawn(mut shutdown: tokio::sync::watch::Receiver<bool>) {
@ -121,8 +121,12 @@ async fn publish_all(client: &async_nats::Client, hive: &str) -> Result<usize> {
tracing::warn!(agent = %spec.name, "agent status: name failed Ident::parse, skipping");
continue;
};
let (status_text, status_set_at, running) =
crate::container_view::read_agent_status_live(&ident).await;
let Some((status_text, status_set_at, running)) =
crate::container_view::read_agent_status_bounded(&ident).await
else {
tracing::warn!(agent = %spec.name, "agent status: unit state unreadable, skipping");
continue;
};
let payload = swarm_queue_client::agent_status::AgentStatus {
status_text,
status_set_at,