refactor(#3034): one quiesce builder, shared by the rebuild and the stop chain
The `Signal` -> `Drain` pair was built in three places, in three different shapes: siblings under `SetWanted` in `stop_chain`, `Drain` nested under a lease-holding `Signal` in `restart_chain`, and — as of this branch — a hybrid in `rebuild_subtree` that was brace-held like the first and nested like the second. `templates::quiesce(builder, agent, brace)` is now the one definition, returning the `Drain` handle a caller edges its stop onto. Both nodes hang off the brace as dep-ordered siblings and declare nothing, borrowing the lease it already holds. That also fixes an inconsistency this branch introduced: the PR argued that a brace makes nesting unnecessary and used it to flatten `StopForUpdate` off `Signal`, then left `Drain` nested under `Signal` two lines away. Nesting is only load-bearing where `Signal` is itself the lease holder. `stop_chain`'s pair loses its own `Agent` declaration as a result — `SetWanted` holds the lease for the subtree, so those were redundant re-entrant borrows. `restart_chain` is left alone and says why in place: it has no brace, so `Signal` holds the lease and the nesting under it is what keeps the grant continuous. Giving it one would unify all three sites at the cost of an extra no-op node on every graceful restart, which an operator would see — not something to change as a side effect of a rebuild-shape PR.
This commit is contained in:
parent
50808007a6
commit
c2eafa7548
3 changed files with 56 additions and 25 deletions
|
|
@ -81,15 +81,10 @@ fn stop_chain(builder: &JobBuilder, agent: &str, graceful: bool, running: bool)
|
|||
// Declaration order is dependency order: the quiesce steps come first so
|
||||
// the `Reconcile` that waits on them can name them.
|
||||
if graceful && running {
|
||||
let signal = builder
|
||||
.node(NodeKind::Signal { agent: a() })
|
||||
.needs(Resource::Agent(a()))
|
||||
.part_of(wanted);
|
||||
let drain = builder
|
||||
.node(NodeKind::Drain { agent: a() })
|
||||
.needs(Resource::Agent(a()))
|
||||
.part_of(wanted)
|
||||
.after_ok(signal);
|
||||
// `SetWanted` is the brace here, so the quiesce pair borrows its grant
|
||||
// rather than declaring the lease itself — same shape the rebuild
|
||||
// template uses, one definition.
|
||||
let drain = super::templates::quiesce(builder, agent, wanted);
|
||||
let _ = builder
|
||||
.node(NodeKind::Reconcile { agent: a() })
|
||||
.needs(Resource::Agent(a()))
|
||||
|
|
@ -155,6 +150,14 @@ fn restart_chain(builder: &JobBuilder, agent: &str, graceful: bool, running: boo
|
|||
// `Reconcile` gates on the last mechanical step. For a non-graceful bounce
|
||||
// that step *is* the root, and the parent gate already orders it — a child
|
||||
// must NOT dep on its own parent (dep-scope), so it takes no sibling edge.
|
||||
//
|
||||
// ⚠️ This is the one quiesce site that does NOT use `templates::quiesce`.
|
||||
// The helper needs a brace holding the lease above the pair; here `Signal`
|
||||
// *is* the holder, and the nesting under it is what keeps the grant
|
||||
// continuous across the bounce. Giving this chain its own brace would
|
||||
// unify all three sites — at the cost of one extra no-op node on every
|
||||
// graceful restart, which an operator would see. Deliberately not done as
|
||||
// a side effect of a rebuild-shape change.
|
||||
if graceful {
|
||||
let signal = builder
|
||||
.node(NodeKind::Signal { agent: a() })
|
||||
|
|
|
|||
Loading…
Reference in a new issue