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

@ -627,19 +627,28 @@ pub async fn unit_state(name: &str) -> UnitState {
}
/// True when the container's systemd unit is active. Used by the dashboard
/// to gate stop/restart buttons. A state that could not be read (see
/// [`running_state`]) is `false`.
/// to gate stop/restart buttons.
///
/// Kept boolean on purpose: nearly every caller is reconcile/power logic
/// asking "is it up? if not, start it", and that question has two answers.
/// A caller that needs to tell *failed* from *stopped* wants
/// [`unit_state`] instead.
///
/// Unbounded: its callers record or act on the answer, so a hung `systemctl`
/// must not read as "not running". Periodic workers use [`running_state`].
pub async fn is_running(name: &str) -> bool {
running_state(name).await == Some(true)
let container = container_name(name);
let unit = format!("container@{container}.service");
Command::new("systemctl")
.args(["is-active", "--quiet", &unit])
.status()
.await
.is_ok_and(|s| s.success())
}
/// Whether the container's systemd unit is active; `None` when `systemctl`
/// could not be run or did not answer within [`IS_ACTIVE_TIMEOUT`].
/// Whether the container's systemd unit is active, for periodic workers that
/// must not stall on a hung `systemctl`; `None` when it could not be run or
/// did not answer within [`IS_ACTIVE_TIMEOUT`].
pub async fn running_state(name: &str) -> Option<bool> {
let container = container_name(name);
let unit = format!("container@{container}.service");