no behaviour change: a pure move of items and tests into new modules, plus visibility edits (pub(crate)) and path updates in sibling modules that named crate-root items. same routes, same OpenAPI, 561 tests before and after. why: #5470, new features stop landing in one 6.4k-line file by default. files outside swarm-controller/src: docs/agent-lifecycle/agent-roster.md, swarm-ui JobsPage.tsx and AgentsPage.tsx, nix/host-modules/swarm-controller.nix and swarm-grafana.nix hold comments that named main.rs for items that moved.
65 lines
2.3 KiB
Rust
65 lines
2.3 KiB
Rust
//! Read-only views of the swarm-level job graph.
|
|
|
|
use axum::{Json, extract::State};
|
|
use hive_jobq_wire::GraphWire as _;
|
|
use serde::Deserialize;
|
|
|
|
use crate::routes::AppState;
|
|
|
|
/// Query params for `GET /api/jobq/graph` — `?states=` narrows to root
|
|
/// groups in the named states, same shape `hive_jobq_wire::parse_states`
|
|
/// parses.
|
|
#[derive(Deserialize, utoipa::IntoParams)]
|
|
pub(crate) struct JobqGraphQuery {
|
|
states: Option<String>,
|
|
}
|
|
|
|
/// Every node of every root group in the swarm-level job graph. Nothing
|
|
/// filters "done and old" here — with zero nodes ever submitted there is
|
|
/// nothing to bound yet, so `graph.roots()` (everything) is the whole
|
|
/// roster passed to [`hive_jobq_wire::GraphWire::wire_snapshot`].
|
|
#[utoipa::path(
|
|
get,
|
|
path = "/api/jobq/graph",
|
|
params(JobqGraphQuery),
|
|
responses((status = 200, description = "every node of every root group, as generic \
|
|
`hive_jobq` graph nodes. `?states=` narrows to root groups in the named states.",
|
|
body = Vec<hive_jobq_wire::GraphNode>)),
|
|
tag = "jobq"
|
|
)]
|
|
pub(crate) async fn get_jobq_graph(
|
|
State(state): State<AppState>,
|
|
axum::extract::Query(q): axum::extract::Query<JobqGraphQuery>,
|
|
) -> Json<Vec<hive_jobq_wire::GraphNode>> {
|
|
let states = hive_jobq_wire::parse_states(q.states.as_deref());
|
|
let sched = state
|
|
.jobq
|
|
.lock()
|
|
.unwrap_or_else(std::sync::PoisonError::into_inner);
|
|
let graph = sched.graph();
|
|
let roots: Vec<hive_jobq::NodeId> = graph.roots().map(|n| n.id).collect();
|
|
let nodes = graph.wire_snapshot(roots);
|
|
Json(hive_jobq_wire::filter_nodes_by_state(
|
|
nodes,
|
|
states.as_deref(),
|
|
))
|
|
}
|
|
|
|
/// Counts by lifecycle state over the same groups `/api/jobq/graph` serves.
|
|
#[utoipa::path(
|
|
get,
|
|
path = "/api/jobq/rollup",
|
|
responses((status = 200, description = "counts by lifecycle state", body = Vec<hive_jobq_wire::StateCount>)),
|
|
tag = "jobq"
|
|
)]
|
|
pub(crate) async fn get_jobq_rollup(
|
|
State(state): State<AppState>,
|
|
) -> Json<Vec<hive_jobq_wire::StateCount>> {
|
|
let sched = state
|
|
.jobq
|
|
.lock()
|
|
.unwrap_or_else(std::sync::PoisonError::into_inner);
|
|
let graph = sched.graph();
|
|
let roots: Vec<hive_jobq::NodeId> = graph.roots().map(|n| n.id).collect();
|
|
Json(hive_jobq_wire::state_rollup(graph, roots))
|
|
}
|