hivectl: batch QueueNodes polling by id set, drop remaining dag wording
This commit is contained in:
parent
309c1c91c6
commit
0c4d56a585
8 changed files with 182 additions and 125 deletions
|
|
@ -379,30 +379,34 @@ impl JobQueue {
|
|||
.collect()
|
||||
}
|
||||
|
||||
/// A node plus its live subtree, as generic wire nodes — the
|
||||
/// `QueueNodes` polling surface behind `hivectl`'s wait/progress loop.
|
||||
/// Sibling of [`Self::snapshot`] (which serves the same graph through
|
||||
/// the typed `DagView`/`NodeView` projection for the dashboard's
|
||||
/// `/api/state.rebuild_queue`), this one goes through
|
||||
/// One or more nodes plus their live subtrees, as generic wire nodes —
|
||||
/// the `QueueNodes` polling surface behind `hivectl`'s wait/progress
|
||||
/// loop. Sibling of [`Self::snapshot`] (which serves the same graph
|
||||
/// through the typed `DagView`/`NodeView` projection for the
|
||||
/// dashboard's `/api/state.rebuild_queue`), this one goes through
|
||||
/// [`GraphWire::wire_snapshot`] instead — no `Done`-node filtering, no
|
||||
/// roll-up field (a node's own `state` answers that, see
|
||||
/// `hive_jobq_wire`'s doc comment). Looks the id up by identity alone —
|
||||
/// no assumption that it names a DAG container or a root; "just show
|
||||
/// whatever the backend sends" for whatever id the caller asks about.
|
||||
/// `hive_jobq_wire`'s doc comment). Looks each id up by identity
|
||||
/// alone — no assumption that it names a DAG container or a root;
|
||||
/// "just show whatever the backend sends" for whatever ids the caller
|
||||
/// asks about. Multiple ids in one call is the normal shape for a
|
||||
/// batch op (e.g. restarting every agent submits one root per agent) —
|
||||
/// callers should request the whole batch together rather than poll
|
||||
/// one id per round-trip.
|
||||
///
|
||||
/// Empty when `id` names no node in the graph. Today that only happens
|
||||
/// for a genuinely unknown id: nothing prunes the graph yet
|
||||
/// (bounded-prune is a Stage-C follow-up, see [`visible_dags`]), so a
|
||||
/// *completed* DAG's nodes keep riding here with a terminal `state`
|
||||
/// rather than disappearing — callers watching for "done" should read
|
||||
/// the root's `state`, not emptiness.
|
||||
/// An id with no matching node in the graph is silently dropped from
|
||||
/// the result rather than erroring the whole batch — some ids in a
|
||||
/// batch may already be evicted while others are still live. Today
|
||||
/// that only happens for a genuinely unknown id: nothing prunes the
|
||||
/// graph yet (bounded-prune is a Stage-C follow-up, see
|
||||
/// [`visible_dags`]), so a *completed* DAG's nodes keep riding here
|
||||
/// with a terminal `state` rather than disappearing — callers
|
||||
/// watching for "done" should read the root's `state`, not absence.
|
||||
#[must_use]
|
||||
pub fn node_subtree(&self, id: u64) -> Vec<GraphNode> {
|
||||
pub fn node_subtrees(&self, ids: &[u64]) -> Vec<GraphNode> {
|
||||
let inner = self.lock();
|
||||
let Some(node) = find_node(&inner, id) else {
|
||||
return Vec::new();
|
||||
};
|
||||
inner.graph().wire_snapshot([node])
|
||||
let roots: Vec<NodeId> = ids.iter().filter_map(|id| find_node(&inner, *id)).collect();
|
||||
inner.graph().wire_snapshot(roots)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -160,8 +160,8 @@ async fn dispatch(req: &HostRequest, coord: Arc<Coordinator>) -> HostResponse {
|
|||
.collect();
|
||||
HostResponse::dags(dags)
|
||||
}
|
||||
HostRequest::QueueNodes { id } => {
|
||||
HostResponse::nodes(coord.job_queue.node_subtree(*id))
|
||||
HostRequest::QueueNodes { ids } => {
|
||||
HostResponse::nodes(coord.job_queue.node_subtrees(ids))
|
||||
}
|
||||
HostRequest::List => HostResponse::list(lifecycle::list().await?),
|
||||
// The agents root is ours and not world-traversable, so this
|
||||
|
|
|
|||
Loading…
Reference in a new issue