jobq: a transient is any running node naming the agent
Per mara on #2822: status is the only test. The agent comes off the node's own payload rather than a declared Resource::Agent edge, so the lease-exempt kinds (Prebuild, MetaSync) that name an agent without holding its lease now light a pill — they are work on that agent. Dropping that test breaks the one-pill-per-agent invariant, since lease-exemption is exactly what lets one DAG build for an agent while another holds its lease. Everything keyed by agent alone had to follow: - reconcile_transients keys (agent, label) via TransientSeen, so a second pill cannot evict the first — and cannot lose its takes_container_down, which the crash watcher reads at clear time. - transient_snapshot returns a Vec per agent for the same reason. The collapse was silent: a Prebuild could evict a StopForUpdate and its deliberate_stop, making an intentional stop report as a crash. - crash_watch asks whether ANY running node expects the container down. - the dashboard renders one row per node instead of one per agent. takes_container_down never reached the frontend; no wire change needed. 315 tests pass unchanged.
This commit is contained in:
parent
6809c782a3
commit
8ce265fdf0
6 changed files with 79 additions and 56 deletions
|
|
@ -91,9 +91,13 @@ fn emit_crash_transitions(coord: &Coordinator, prev: &HashSet<String>, current:
|
|||
// Two sources, because a container can go down on purpose either way:
|
||||
// a running queue node that declared it takes the container down, or a
|
||||
// no-node operation (destroy, migration) holding a suppression guard.
|
||||
// `any`, not "the" pill: an agent can have several running nodes at
|
||||
// once (a lease-exempt build alongside a lease-holding stop), and it
|
||||
// only takes one of them expecting the container down for this to be
|
||||
// a deliberate stop rather than a crash.
|
||||
let active = transients
|
||||
.get(stopped)
|
||||
.map(|st| st.deliberate_stop)
|
||||
.map(|sts| sts.iter().any(|st| st.deliberate_stop))
|
||||
.or_else(|| coord.crash_watch_suppressed(stopped).then_some(true));
|
||||
let recently_cleared = recent.get(stopped).copied();
|
||||
if is_deliberate_stop(active, recently_cleared) {
|
||||
|
|
|
|||
Loading…
Reference in a new issue