job_queue: grow the rebuild subgraph from DeployApply (#2664)
The config-PR deploy's apply node still did the whole container rebuild inline, through the last surviving `lifecycle::rebuild_no_meta` call. It now merges, opens the two-phase meta deploy, and returns the ordinary rebuild chain as a subgraph the scheduler grafts into the live DAG under it. A new `FinalizeDeploy` node, gated on that graft, plants the deploy tag and commits the staged lock. Net effect: "did the agent come back up?" is answered by `Reconcile` succeeding, the same way it is for every other rebuild, instead of by a fused inline start — and each deploy phase is its own queue node, so the dashboard shows which one is running. The grafted nodes root on the apply node, so they land inside `DeployWindow`'s subtree and re-enter the meta window and build slot it already holds rather than deadlocking against them. The new happy-path test runs on a one-slot queue specifically to pin that down. `FinalizeDeploy`'s two git writes are fatal, deliberately: they are what tells `DeployTail` a deploy confirmed good, so a node that merely warned on them could report success while leaving the tail looking at the git state of a failure — and the tail would then roll a good deploy back. The trailing `meta::finalize_deploy` stays warn-only, since by then the container already runs the new config. The `failed/<id>` annotated tag moves into the tail, which is now the only place holding a failed deploy. It reads the reason off the DAG via a new `JobQueue::first_error`, and is gated on `main` having actually moved — the rollback ref is parked *before* the merge, so its existence alone does not mean a merge happened, and a pre-merge rejection must not tag the previous, innocent head. Removing the last inline rebuild orphaned a chain of now-dead code: `rebuild_no_meta`, `container_exists`, `Coordinator::set_queue_build_log` and `JobQueue::set_build_log_id_running`, all deleted here.
This commit is contained in:
parent
7b2645078a
commit
3429a8c5a6
10 changed files with 388 additions and 257 deletions
|
|
@ -500,17 +500,6 @@ impl JobQueue {
|
|||
true
|
||||
}
|
||||
|
||||
/// Link a `build_logs` row to the DAG's currently-running node — DAG-id-only
|
||||
/// compatibility surface (approval pipeline callbacks).
|
||||
pub fn set_build_log_id_running(&self, dag_id: u64, log_id: i64) -> bool {
|
||||
let mut inner = self.lock();
|
||||
let Some(node_id) = inner.running_node_of(dag_id) else {
|
||||
return false;
|
||||
};
|
||||
inner.node_rt.entry(node_id).or_default().build_log_id = Some(log_id);
|
||||
true
|
||||
}
|
||||
|
||||
/// The `build_logs` row id linked to the wire node id `node_id`, if any —
|
||||
/// the lookup behind the `GET /api/build-log/<node_id>` query endpoint (the
|
||||
/// client fetches a node's captured build output on demand rather than
|
||||
|
|
@ -526,6 +515,22 @@ impl JobQueue {
|
|||
.and_then(|(_, rt)| rt.build_log_id)
|
||||
}
|
||||
|
||||
/// The first failed node's error in `dag_id`, if any has failed yet.
|
||||
///
|
||||
/// Unlike the roll-up summary this is readable *mid-flight*, which is the
|
||||
/// point: a compensation node runs `AfterAny` its subject, so when it asks,
|
||||
/// the DAG is still `Finishing` (the compensation node itself is running)
|
||||
/// while the node it is compensating for has already settled `Failed`. That
|
||||
/// lets the compensation annotate its bookkeeping with the reason the deploy
|
||||
/// failed, instead of having the error handed down from the node that hit
|
||||
/// it. `None` when nothing has failed — the ordinary success path.
|
||||
#[must_use]
|
||||
pub fn first_error(&self, dag_id: u64) -> Option<String> {
|
||||
let inner = self.lock();
|
||||
let container = inner.container(dag_id)?;
|
||||
inner.dag_first_error(container)
|
||||
}
|
||||
|
||||
/// A DAG's terminal roll-up summary, computed on demand from its container.
|
||||
/// `None` if the DAG id is unknown. Test-only — production reads the summary
|
||||
/// `complete_node` returns when the container rolls up terminal.
|
||||
|
|
|
|||
Loading…
Reference in a new issue