feat(#2349): fan reconcile's start/stop out as first-class dag nodes
This commit is contained in:
parent
7b1b1d9db8
commit
79d4c345bb
4 changed files with 156 additions and 63 deletions
|
|
@ -169,6 +169,40 @@ impl JobQueue {
|
|||
ids
|
||||
}
|
||||
|
||||
/// Append a node into a *live* (non-terminal) DAG at runtime,
|
||||
/// depending `AfterOk` on `dep_on` (the node that emitted it). Lets a
|
||||
/// planner node — e.g. [`NodeKind::Reconcile`] — fan a mechanical
|
||||
/// sub-step ([`NodeKind::Start`] / [`NodeKind::Stop`]) out as a
|
||||
/// first-class node in the *same* DAG.
|
||||
///
|
||||
/// Must be called *before* the emitting node's [`Self::complete_node`]
|
||||
/// so the DAG doesn't roll terminal with the new node still pending —
|
||||
/// that keeps the lease-window transient held across the sub-step and
|
||||
/// lets the appended node's `AfterOk` dep resolve as soon as the
|
||||
/// emitter settles `Done`. No-op (returns `None`) if the DAG is gone.
|
||||
pub fn append_node(&self, dag_id: u64, kind: NodeKind, dep_on: NodeId) -> Option<NodeId> {
|
||||
let mut inner = self.inner.lock().expect("job_queue mutex poisoned");
|
||||
let dag = inner.dags.iter_mut().find(|d| d.id == dag_id)?;
|
||||
let new_id: NodeId = u32::try_from(dag.nodes.len()).unwrap_or(u32::MAX);
|
||||
dag.nodes.push(Node {
|
||||
id: new_id,
|
||||
kind,
|
||||
deps: vec![model::Dep {
|
||||
on: dep_on,
|
||||
when: DepWhen::AfterOk,
|
||||
}],
|
||||
state: State::Queued,
|
||||
step: None,
|
||||
build_log_id: None,
|
||||
started_at: None,
|
||||
finished_at: None,
|
||||
error: None,
|
||||
});
|
||||
drop(inner);
|
||||
self.notify.notify_one();
|
||||
Some(new_id)
|
||||
}
|
||||
|
||||
fn dedup_target<'a>(inner: &'a mut Inner, spec: &DagSpec) -> Option<&'a mut Dag> {
|
||||
inner.dags.iter_mut().find(|d| {
|
||||
d.rollup() == State::Queued
|
||||
|
|
|
|||
Loading…
Reference in a new issue