feat(#2349): fan reconcile's start/stop out as first-class dag nodes

This commit is contained in:
damocles 2026-07-11 23:33:45 +02:00 committed by mara
commit 79d4c345bb
4 changed files with 156 additions and 63 deletions

View file

@ -92,14 +92,32 @@ async fn handle_completion(
done: NodeDone,
) {
let NodeDone { claim, result } = done;
let (queue_result, fanout) = match result {
match result {
Ok(output) => {
tracing::info!(
dag = claim.dag_id,
node = claim.node_id,
"job_queue: node done"
);
(Ok(()), output.fanout)
// Append any in-DAG sub-step nodes (e.g. a `Reconcile`
// planner's `Start` / `Stop`) BEFORE completing this node, so
// completing it doesn't roll the DAG terminal while the
// appended work is still pending — that keeps the lease-window
// transient held across the sub-step. Each depends `AfterOk`
// on this node, so it becomes ready the instant this one
// settles `Done` just below.
for kind in output.append_nodes {
coord
.job_queue
.append_node(claim.dag_id, kind, claim.node_id);
}
coord
.job_queue
.complete_node(claim.dag_id, claim.node_id, Ok(()));
if !output.fanout.is_empty() {
let specs = fanout_specs(&claim, output.fanout);
coord.job_queue.append_children(specs);
}
}
Err(e) => {
let msg = format!("{e:#}");
@ -111,15 +129,10 @@ async fn handle_completion(
error = %msg,
"job_queue: node failed"
);
(Err(msg), Vec::new())
coord
.job_queue
.complete_node(claim.dag_id, claim.node_id, Err(msg));
}
};
coord
.job_queue
.complete_node(claim.dag_id, claim.node_id, queue_result);
if !fanout.is_empty() {
let specs = fanout_specs(&claim, fanout);
coord.job_queue.append_children(specs);
}
process_terminals(coord, transients).await;
coord.emit_rebuild_queue_snapshot();