job_queue: delete the cancelled-power-op intent revert
The revert hook is dead by construction, so it can only ever be wrong. DAG state `Cancelled` has exactly one producer: `JobQueue::cancel`, which refuses unless every work node is still `Pending`. A cancel *cascade* (some node failed, downstream cancelled) rolls up `Failed` instead — `dag_rollup` short-circuits on any failed subtree node. So on a DAG that reaches `Cancelled`, no node ever executed: the `SetWanted` head provably never ran and `wanted` still reads whatever the operator last set it to. There is therefore nothing to revert, and `revert_intent` did not revert anything — it wrote `Wanted::from_running(observed)`, i.e. the agent's *observed* state, over an intent the DAG never touched. Harmless when observed already matched, silent corruption otherwise: cancel a queued start for an agent that is down but `wanted = Up` (crashed, or caught mid-bounce) and the intent flips to `Offline`, leaving it deliberately-stopped as far as reconcile and crash-watch are concerned. The hook made sense when `set_wanted` was a pre-submit side effect written before the DAG ran; moving it into the DAG as a node left the hook vestigial. Drop `HookKind::RevertIntent`, `revert_intent`, and the power-op arm of `terminal_hook` — start / stop / graceful-stop now settle with no terminal hook, same as restart always did. The test asserts the general statement across restart/stop/start x graceful x running: stop and start carry a `SetWanted` head, and cancelling them still fires no hook.
This commit is contained in:
parent
7589f4c06c
commit
5c4a637941
4 changed files with 64 additions and 79 deletions
|
|
@ -112,7 +112,6 @@ pub(crate) async fn run_terminal_hook(coord: &Arc<Coordinator>, terminal: &super
|
|||
crate::actions::resolve_approval_dag(coord, terminal).await;
|
||||
}
|
||||
Some(super::HookKind::EmitRebuilt) => emit_rebuilt(coord, terminal),
|
||||
Some(super::HookKind::RevertIntent) => revert_intent(coord, terminal).await,
|
||||
None => {}
|
||||
}
|
||||
}
|
||||
|
|
@ -141,30 +140,6 @@ fn emit_rebuilt(coord: &Arc<Coordinator>, terminal: &super::TerminalDag) {
|
|||
}
|
||||
}
|
||||
|
||||
/// Power-op hook: on a *cancelled* DAG, revert each targeted agent's `wanted`
|
||||
/// intent to its observed state — the operator's cancel means "don't do it", so
|
||||
/// the intent snaps back instead of the flip executing as a surprise side effect
|
||||
/// of some later reconcile. Noop on any non-cancelled outcome.
|
||||
///
|
||||
/// Only valid for templates carrying a `SetWanted` head (start / stop): the
|
||||
/// revert writes *observed* state, so dispatching it for a template that never
|
||||
/// wrote an intent doesn't restore anything — it invents one. See
|
||||
/// [`super::terminal_hook`].
|
||||
async fn revert_intent(coord: &Arc<Coordinator>, terminal: &super::TerminalDag) {
|
||||
if terminal.state != State::Cancelled {
|
||||
return;
|
||||
}
|
||||
for agent in &terminal.agents {
|
||||
let running = crate::lifecycle::is_running(agent).await;
|
||||
if let Err(e) = coord
|
||||
.power
|
||||
.set(agent, crate::power::Wanted::from_running(running))
|
||||
{
|
||||
tracing::warn!(%agent, error = ?e, "agent_power: cancel revert failed");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Write the agent's durable power intent — the DAG-node form of the old
|
||||
/// pre-submit `set_wanted` side effect. Store-only (no container touch), so
|
||||
/// build-slot-exempt; but it takes the agent's lifecycle lease (see
|
||||
|
|
|
|||
Loading…
Reference in a new issue