fix(#2515): derive per-agent in-flight badge from node state, not DAG state
inFlightOpsByAgent() read e.agent, a DAG-level field that no longer exists (agent moved to per-node when DAGs became agent-per-node). So the SW4RM tab's 'building...'/'meta-updating...' badges never matched any real agent, and multi-agent DAGs (a startup sweep's MetaLock cascade, a hive-wide restart) showed nothing at all on the per-agent cards even while the rebuild queue clearly had them in flight. Derive each agent's in-flight kind+state from its own node(s) within the entry instead: a DAG can be 'running' overall while a given agent's subgraph hasn't started (still queued behind an earlier node in its chain), so per-node state is also more accurate than the old per-DAG state for the badge, not just more available.
This commit is contained in:
parent
990f021c32
commit
614e8c6d5a
1 changed files with 26 additions and 9 deletions
|
|
@ -59,11 +59,18 @@ export function applyRebuildQueueChanged(ev) {
|
|||
// See docs/web-ui.md::Container row for the badge taxonomy.
|
||||
renderContainersFromState();
|
||||
}
|
||||
// Map from agent name -> highest-priority in-flight queue entry
|
||||
// (`running` beats `queued`). Used by the container row renderer
|
||||
// to surface "building..." / "meta-updating..." badges on the
|
||||
// SW4RM tab when an op is still in the rebuild queue but no
|
||||
// operator-initiated transient is set.
|
||||
// Map from agent name -> highest-priority in-flight op ({ kind, state })
|
||||
// (`running` beats `queued`). Used by the container row renderer to
|
||||
// surface "building..." / "meta-updating..." badges on the SW4RM tab
|
||||
// when an op is still in the rebuild queue but no operator-initiated
|
||||
// transient is set.
|
||||
//
|
||||
// Agent is per-node, not per-DAG (a DAG can span agents — e.g. the
|
||||
// startup sweep's MetaLock cascade, or a hive-wide restart), so this
|
||||
// derives each agent's in-flight state from its own node(s) within the
|
||||
// entry rather than the DAG's overall `state`/`kind` — a DAG can be
|
||||
// `running` overall while a given agent's subgraph hasn't started yet
|
||||
// (still queued behind an earlier node in its chain), and vice versa.
|
||||
function inFlightOpsByAgent() {
|
||||
const out = new Map();
|
||||
for (const e of rebuildQueueState) {
|
||||
|
|
@ -74,10 +81,20 @@ function inFlightOpsByAgent() {
|
|||
// surfacing if the spawn op happens to land in the queue
|
||||
// while the row exists transiently.
|
||||
if (e.kind === 'spawn') continue;
|
||||
const cur = out.get(e.agent);
|
||||
// Prefer running over queued; otherwise keep the first match.
|
||||
if (!cur || (cur.state === 'queued' && e.state === 'running')) {
|
||||
out.set(e.agent, e);
|
||||
const perAgentState = new Map();
|
||||
for (const n of e.nodes || []) {
|
||||
if (!n.agent) continue;
|
||||
if (n.state !== 'queued' && n.state !== 'running') continue;
|
||||
const cur = perAgentState.get(n.agent);
|
||||
if (!cur || (cur === 'queued' && n.state === 'running')) {
|
||||
perAgentState.set(n.agent, n.state);
|
||||
}
|
||||
}
|
||||
for (const [agent, state] of perAgentState) {
|
||||
const cur = out.get(agent);
|
||||
if (!cur || (cur.state === 'queued' && state === 'running')) {
|
||||
out.set(agent, { kind: e.kind, state });
|
||||
}
|
||||
}
|
||||
}
|
||||
return out;
|
||||
|
|
|
|||
Loading…
Reference in a new issue