refactor(#2756): declare the terminal hook instead of inferring it
`Template` was a DAG-level enum that three different things read back out: `terminal_hook()` mapped it to a side effect, the retention pass bucketed history by it, and a tracing field printed it. None of those needed a *label* — they needed the two facts the label happened to encode. So the enum was a lossy stand-in for intent, and every new DAG shape had to pick the variant whose inferred behaviour matched, whether or not the name fit (`reparent` rode `MetaUpdate` for exactly this reason, with a 10-line comment apologising for it). Replace the inference with a declaration: `DagSpec.hook: Option<HookKind>`. Only the builder assembling a DAG knows why it did so, so only the builder can say what should happen when it settles. `run_terminal_hook` becomes a field read, and `reparent`'s apology becomes `hook: None`. Hook assignment is byte-identical to the old precedence rule (`approval_id.is_some()` wins, then `Rebuild | PermChange`), checked site by site; `meta_update` is the only builder with a variable approval id and so the only remaining conditional. Retention loses the per-template bucket with the enum that keyed it. The dashboard renders one recent-builds list, so one flat newest-first cap (`MAX_HISTORY_DAGS`) bounds it. `HISTORY_GRACE_SECS` goes too — it existed to stop a burst of same-template DAGs evicting each other inside one poll interval, which is not a failure mode a flat cap has. That takes `snapshot_capped()` and the `snapshot_no_grace()` test hook with it. The queue is runtime-only (empty graph on boot), so the serde changes carry no migration risk.
This commit is contained in:
parent
a8728ac532
commit
ca7146e4f0
8 changed files with 113 additions and 241 deletions
|
|
@ -24,7 +24,7 @@
|
|||
|
||||
use std::sync::Arc;
|
||||
|
||||
use super::model::{DagSpec, Dep, NodeKind, NodeSpec, Template};
|
||||
use super::model::{DagSpec, Dep, NodeKind, NodeSpec};
|
||||
use super::templates::{after_ok, child, node, rebuild_nodes};
|
||||
use super::{Source, templates};
|
||||
use crate::coordinator::{Coordinator, TransientKind};
|
||||
|
|
@ -188,16 +188,17 @@ fn concat_subgraphs(chains: Vec<Vec<NodeSpec>>) -> Vec<NodeSpec> {
|
|||
out
|
||||
}
|
||||
|
||||
/// Wrap assembled power-op `nodes` in a `DagSpec`.
|
||||
/// Wrap assembled power-op `nodes` in a `DagSpec`. No terminal hook: a power
|
||||
/// op's effect is its nodes (`SetWanted` + `Reconcile`), with nothing left to
|
||||
/// do once they settle.
|
||||
fn power_dag(
|
||||
template: Template,
|
||||
transient: TransientKind,
|
||||
source: Source,
|
||||
reason: String,
|
||||
nodes: Vec<NodeSpec>,
|
||||
) -> DagSpec {
|
||||
DagSpec {
|
||||
template,
|
||||
hook: None,
|
||||
source,
|
||||
reason,
|
||||
approval_id: None,
|
||||
|
|
@ -223,13 +224,7 @@ pub(crate) fn stop_spec(
|
|||
.iter()
|
||||
.map(|(agent, running)| stop_chain(agent, graceful, *running))
|
||||
.collect();
|
||||
let template = if graceful {
|
||||
Template::GracefulStop
|
||||
} else {
|
||||
Template::Stop
|
||||
};
|
||||
power_dag(
|
||||
template,
|
||||
TransientKind::Stopping,
|
||||
source,
|
||||
reason,
|
||||
|
|
@ -256,13 +251,7 @@ pub(crate) fn start_spec(
|
|||
} else {
|
||||
TransientKind::Starting
|
||||
};
|
||||
power_dag(
|
||||
Template::Start,
|
||||
transient,
|
||||
source,
|
||||
reason,
|
||||
concat_subgraphs(chains),
|
||||
)
|
||||
power_dag(transient, source, reason, concat_subgraphs(chains))
|
||||
}
|
||||
|
||||
/// Assemble the restart DAG from explicit `(agent, running)` targets.
|
||||
|
|
@ -276,13 +265,7 @@ pub(crate) fn restart_spec(
|
|||
.iter()
|
||||
.map(|(agent, running)| restart_chain(agent, graceful, *running))
|
||||
.collect();
|
||||
let template = if graceful {
|
||||
Template::GracefulRestart
|
||||
} else {
|
||||
Template::Restart
|
||||
};
|
||||
power_dag(
|
||||
template,
|
||||
TransientKind::Restarting,
|
||||
source,
|
||||
reason,
|
||||
|
|
|
|||
Loading…
Reference in a new issue