jobq: a generic per-state roll-up, served beside the graph
A consumer that wants "how much is in flight" — a summary line, a badge, a health check — had to fetch the whole graph and tally it client-side, on every poll, in every consumer. `hive_jobq_wire::state_rollup` counts `roots` and their subtrees by state, straight off a `Graph<N, R>` with **no bound on either parameter**. A node's state is a scheduler concept, so counting by state needs to know nothing about what the payload or the resource are; bounding it like the projection does would make a host implement two display traits to be allowed to count, which is a requirement about rendering imposed on arithmetic. It takes the roots for the same reason `wire_snapshot` does — which groups are in view is the host's policy, and nothing is ever removed from a graph — so passing the same set makes the roll-up describe exactly the graph beside it. Each entry carries BOTH counts: `nodes` (the whole subtree) and `roots` (just the group tops). One rebuild is ~7 nodes and 1 root, so a summary meaning *operations* and one meaning *steps* are different numbers over the same queue, and picking one here would make this crate decide what counts as a job — the domain question it exists not to answer. It reports both structural facts; the viewer chooses. A pair, not a map: JSON object keys are strings, so a map would spell the state twice and give the wire no ordering. Every state rides with its zeros in a fixed order, so a consumer can index positionally and never handles a missing bucket. Tallying positionally against `ALL_STATES` means a new upstream `State` fails the exhaustive match in `state_index` rather than silently landing in an existing bucket. hive-c0re serves it at `GET /api/jobq/rollup`. The queue-side method is a call site, not an implementation: it supplies the lock and the same `visible_roots` as `graph_snapshot`, so the summary cannot describe a different visible set than the graph it summarises.
This commit is contained in:
parent
b04e7d985d
commit
9e7a2002d1
4 changed files with 195 additions and 3 deletions
|
|
@ -368,6 +368,18 @@ impl JobQueue {
|
|||
inner.graph().wire_snapshot(visible_roots(&inner))
|
||||
}
|
||||
|
||||
/// Per-state counts over the **same** groups [`Queue::graph_snapshot`]
|
||||
/// serves.
|
||||
///
|
||||
/// Supplies the same two things and nothing else: the lock, and
|
||||
/// [`visible_roots`]. The counting is [`hive_jobq_wire::state_rollup`]'s and
|
||||
/// is generic over the payload — this is a call site, not an implementation.
|
||||
#[must_use]
|
||||
pub fn state_rollup(&self) -> Vec<hive_jobq_wire::StateCount> {
|
||||
let inner = self.lock();
|
||||
hive_jobq_wire::state_rollup(inner.graph(), visible_roots(&inner))
|
||||
}
|
||||
|
||||
/// Snapshot every live + retained DAG for `/api/state` + `RebuildQueueChanged`.
|
||||
#[must_use]
|
||||
pub fn snapshot(&self) -> Vec<DagView> {
|
||||
|
|
|
|||
Loading…
Reference in a new issue