job_queue: retire the now-off-wire step sub-step label
The `step` label was taken off the wire in #2661, when each deploy phase became a first-class DAG node. Since then it has been written but never read: `NodeRuntime` derives only `Debug, Default, Clone` — no serde — so the field could not reach any client, and the only reads of it were the dedup checks inside its own setters. This deletes the machinery. Removed: - `NodeRuntime.step`, `set_step`, `set_step_running`, and the `rt.step = None` clear in `complete_node`. `NodeRuntime` keeps its remaining `build_log_id` field (deliberately still a struct — collapsing it to a bare `Option<i64>` would churn every call site for no gain). - `Ctx::step` and its ~15 call sites in `job_queue/exec.rs`. `Ctx` itself stays: it is the build-log sink, which `run_prebuild` and `run_swap` still use. - `Coordinator::set_queue_step` and its 11 callers in `actions.rs`. - `JobQueue::running_node_of`, reachable only from `set_queue_step`. - `swap_update`'s `on_step` parameter and its one body call. - The `set_step_only_on_running_and_signals_change` test. Dropping the calls orphaned parameters, which are removed with their call sites: `ctx` on ten executors that used it only as a step sink, and `queue_entry_id` on `run_deploy_merge_verify` / `run_deploy_apply` / `run_finalize_deploy` plus both `coord` and `queue_entry_id` on `prepare_applied_target`. `run_deploy_tail` KEEPS its `queue_entry_id` — that one has a genuine surviving use (the build-log link in the failure comment posted to the PR). One behavioural change, called out so it is not mistaken for a dropped dashboard refresh: `Ctx::step` and `set_queue_step` each emitted a `rebuild_queue_changed` snapshot when the label changed, and those emissions go away with them. This is safe — the snapshot payload has no step field, so those pushes carried nothing a client could observe. Real state transitions still emit from the scheduler's claim and completion paths, from `submit`, and from the three `actions.rs` sites. Net effect is strictly fewer redundant SSE pushes. Docs: `docs/coordinator.md` still listed `step` as a `NodeView` wire field and `docs/web-ui/dashboard.md` documented a cyan `↳ <step>` sub-line under each queue row. Neither has existed since #2661 — both corrected here, plus the `job_queue/model.rs` module doc. Not touched: `frontend/packages/dashboard/src/system-sections.css` has a dead `.rqe-step` rule with no JS referencing it. Left for the frontend owner rather than deleted here. Closes: #2664
This commit is contained in:
parent
ff62bf2235
commit
1db3cc32a1
9 changed files with 51 additions and 210 deletions
|
|
@ -99,11 +99,10 @@ pub struct TerminalDag {
|
|||
|
||||
/// Per-node runtime metadata the crate graph doesn't carry. Lifecycle
|
||||
/// (`started_at` / `finished_at` / `error`) lives on the `hive_jobq::Node`
|
||||
/// itself now, so only the two host-side extras remain: the live sub-step
|
||||
/// label and the build-log row link (the client fetches the log by node id).
|
||||
/// itself now, so only the build-log row link remains host-side (the
|
||||
/// client fetches the log by node id).
|
||||
#[derive(Debug, Default, Clone)]
|
||||
struct NodeRuntime {
|
||||
step: Option<String>,
|
||||
build_log_id: Option<i64>,
|
||||
}
|
||||
|
||||
|
|
@ -129,8 +128,8 @@ struct DagMeta {
|
|||
/// [`QueueInner::dag_meta`]). One shared crate [`Graph`] holds every DAG.
|
||||
struct QueueInner {
|
||||
sched: Scheduler<NodeKind, Resource>,
|
||||
/// Per-node runtime metadata (build-log id, step, timestamps, error) —
|
||||
/// mutable after insert, so it can't ride the immutable node payload.
|
||||
/// Per-node runtime metadata (the build-log id) — mutable after
|
||||
/// insert, so it can't ride the immutable node payload.
|
||||
node_rt: HashMap<NodeId, NodeRuntime>,
|
||||
}
|
||||
|
||||
|
|
@ -405,14 +404,11 @@ impl JobQueue {
|
|||
let mut inner = self.lock();
|
||||
// The failure reason + `finished_at` are stamped onto the graph `Node`
|
||||
// by the scheduler (the reason rides `Outcome::Failed`); no host-side
|
||||
// copy. We only clear the live sub-step label here.
|
||||
// copy, so there is nothing to clear here.
|
||||
let outcome = match result {
|
||||
Ok(()) => Outcome::Done,
|
||||
Err(e) => Outcome::Failed(truncate_error(&e)),
|
||||
};
|
||||
if let Some(rt) = inner.node_rt.get_mut(&node_id) {
|
||||
rt.step = None;
|
||||
}
|
||||
let container = inner.dag_of(node_id);
|
||||
inner.sched.complete(node_id, outcome);
|
||||
// If this completion rolled the DAG's container up to a terminal state,
|
||||
|
|
@ -461,35 +457,6 @@ impl JobQueue {
|
|||
terminal
|
||||
}
|
||||
|
||||
/// Set the step label on a `Running` node. Returns `true` when it changed.
|
||||
pub fn set_step(&self, dag_id: u64, node_id: NodeId, step: &str) -> bool {
|
||||
let mut inner = self.lock();
|
||||
if inner.dag_of(node_id).map(NodeId::get) != Some(dag_id) || !inner.node_running(node_id) {
|
||||
return false;
|
||||
}
|
||||
let rt = inner.node_rt.entry(node_id).or_default();
|
||||
if rt.step.as_deref() == Some(step) {
|
||||
return false;
|
||||
}
|
||||
rt.step = Some(step.to_owned());
|
||||
true
|
||||
}
|
||||
|
||||
/// Set the step label on the DAG's currently-running node — the DAG-id-only
|
||||
/// compatibility surface for the opaque approval pipeline.
|
||||
pub fn set_step_running(&self, dag_id: u64, step: &str) -> bool {
|
||||
let mut inner = self.lock();
|
||||
let Some(node_id) = inner.running_node_of(dag_id) else {
|
||||
return false;
|
||||
};
|
||||
let rt = inner.node_rt.entry(node_id).or_default();
|
||||
if rt.step.as_deref() == Some(step) {
|
||||
return false;
|
||||
}
|
||||
rt.step = Some(step.to_owned());
|
||||
true
|
||||
}
|
||||
|
||||
/// Link a `build_logs` row to a specific `Running` node.
|
||||
pub fn set_build_log_id(&self, dag_id: u64, node_id: NodeId, log_id: i64) -> bool {
|
||||
let mut inner = self.lock();
|
||||
|
|
@ -670,15 +637,6 @@ impl QueueInner {
|
|||
})
|
||||
}
|
||||
|
||||
/// The DAG's currently-running work node, if any (the opaque approval
|
||||
/// pipeline's single-node DAGs make this exact).
|
||||
fn running_node_of(&self, dag_id: u64) -> Option<NodeId> {
|
||||
let container = self.container(dag_id)?;
|
||||
self.subtree(container)
|
||||
.into_iter()
|
||||
.find(|&id| self.node_running(id))
|
||||
}
|
||||
|
||||
/// Roll-up state over a DAG's work nodes: `Failed` if any failed; else
|
||||
/// `Running` if any running; else `Queued` if any queued; else `Cancelled`
|
||||
/// if any cancelled; else `Done`. (Kept eager over the subtree — a failed
|
||||
|
|
|
|||
Loading…
Reference in a new issue