jobq: completion is pub(crate); the DAG container is not a special case
`submit` used to complete the container node by hand, right after inserting it, so it would park in `Finishing` and its children unblock. That was the last caller of `Scheduler::complete` outside the crate, and the justification was that the container "never needs claiming or executing". It does, though, in the sense that matters: it is a node with no logic of its own, and the scheduler already knows what to do with one. It declares no resources, so it is claimable the moment it is inserted; `run_node`'s `Dag` arm already returns `Ok(())`, exactly as it does for `DeployWindow`, which is the same shape and was never special-cased. Deleting the inline completion costs one claim round-trip and removes the only reason the crate had to expose completion at all. `complete` is `pub(crate)` now. Completion is reachable only from inside the future `claim_next` hands back, so a node cannot be finished without the claim it answers, and cannot be claimed without the future that finishes it. That was the point of the seam.
This commit is contained in:
parent
e646656c92
commit
a3a0b34668
2 changed files with 10 additions and 13 deletions
|
|
@ -201,6 +201,12 @@ impl JobQueue {
|
|||
/// roots re-parented to the container). Returns the container's id as the
|
||||
/// DAG id — its rolled-up state is the DAG state.
|
||||
///
|
||||
/// The container is an ordinary node: it declares no resources, so the
|
||||
/// scheduler claims it on the next pass, runs its (empty) logic and parks
|
||||
/// it in `Finishing`, at which point its children become runnable. Nothing
|
||||
/// here completes it by hand — a node with no work of its own still goes
|
||||
/// the way every other node goes.
|
||||
///
|
||||
/// Takes the spec's recipe by generic, not as a boxed closure: a spec
|
||||
/// travels from the template that built it directly into this call, so
|
||||
/// there is nothing to allocate for.
|
||||
|
|
@ -222,11 +228,6 @@ impl JobQueue {
|
|||
)
|
||||
.map_err(|e| anyhow::anyhow!("job_queue: container insert failed: {e}"))?;
|
||||
insert_group(&mut inner, spec.declare, Some(container))?;
|
||||
// Settle the container's own (no-op) logic immediately so it parks in
|
||||
// `Finishing` and its children become runnable — it never needs claiming
|
||||
// or executing, and stays out of `claim_ready`. It rolls up terminal when
|
||||
// its whole subtree settles (that's the DAG-done signal).
|
||||
inner.complete(container, Outcome::Done);
|
||||
drop(inner);
|
||||
self.notify.notify_one();
|
||||
Ok(container.get())
|
||||
|
|
|
|||
|
|
@ -306,14 +306,10 @@ impl<N, R: Clone + Eq + Hash> Scheduler<N, R> {
|
|||
/// propagates up the parent chain. Claim again afterwards to start
|
||||
/// newly-unblocked work.
|
||||
///
|
||||
/// ⚠️ **Still `pub` for one caller**, and that caller is the last hole in
|
||||
/// this wall: a host inserting a group root with no logic of its own
|
||||
/// completes it immediately so it parks in `Finishing` and its children
|
||||
/// become runnable. That is a statement about the *node* ("this one has no
|
||||
/// work"), not an event to report, and it wants to be expressible at
|
||||
/// insert time so completion can go `pub(crate)` alongside
|
||||
/// [`Self::complete_growing`].
|
||||
pub fn complete(&mut self, id: NodeId, outcome: Outcome) {
|
||||
/// `pub(crate)`: completion is reachable only from inside the future
|
||||
/// [`Self::claim_next`] hands back, so it is not expressible without the
|
||||
/// claim it answers.
|
||||
pub(crate) fn complete(&mut self, id: NodeId, outcome: Outcome) {
|
||||
match outcome {
|
||||
Outcome::Failed(error) => {
|
||||
// Record the reason before the terminal transition so it's set
|
||||
|
|
|
|||
Loading…
Reference in a new issue