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.
|
// See docs/web-ui.md::Container row for the badge taxonomy.
|
||||||
renderContainersFromState();
|
renderContainersFromState();
|
||||||
}
|
}
|
||||||
// Map from agent name -> highest-priority in-flight queue entry
|
// Map from agent name -> highest-priority in-flight op ({ kind, state })
|
||||||
// (`running` beats `queued`). Used by the container row renderer
|
// (`running` beats `queued`). Used by the container row renderer to
|
||||||
// to surface "building..." / "meta-updating..." badges on the
|
// surface "building..." / "meta-updating..." badges on the SW4RM tab
|
||||||
// SW4RM tab when an op is still in the rebuild queue but no
|
// when an op is still in the rebuild queue but no operator-initiated
|
||||||
// operator-initiated transient is set.
|
// 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() {
|
function inFlightOpsByAgent() {
|
||||||
const out = new Map();
|
const out = new Map();
|
||||||
for (const e of rebuildQueueState) {
|
for (const e of rebuildQueueState) {
|
||||||
|
|
@ -74,10 +81,20 @@ function inFlightOpsByAgent() {
|
||||||
// surfacing if the spawn op happens to land in the queue
|
// surfacing if the spawn op happens to land in the queue
|
||||||
// while the row exists transiently.
|
// while the row exists transiently.
|
||||||
if (e.kind === 'spawn') continue;
|
if (e.kind === 'spawn') continue;
|
||||||
const cur = out.get(e.agent);
|
const perAgentState = new Map();
|
||||||
// Prefer running over queued; otherwise keep the first match.
|
for (const n of e.nodes || []) {
|
||||||
if (!cur || (cur.state === 'queued' && e.state === 'running')) {
|
if (!n.agent) continue;
|
||||||
out.set(e.agent, e);
|
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;
|
return out;
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue