feat(#2392): group boot sweep + reconciles under one boot dag
This commit is contained in:
parent
6e0f6893cf
commit
16f69ca890
6 changed files with 111 additions and 23 deletions
|
|
@ -273,10 +273,52 @@ pub async fn run(coord: Arc<Coordinator>) -> Result<()> {
|
|||
"boot reconcile"
|
||||
);
|
||||
|
||||
// Sweep parent whenever ANY marker is stale — even when every
|
||||
// stale agent is wanted-offline: the hyperhive lock bump must land
|
||||
// now so their later start-upgrade rebuilds build against it.
|
||||
// No stale agents ⇒ no sweep ⇒ no meta commit on a no-change boot.
|
||||
submit_boot_tree(&coord, any_stale, fanout, drifted, n_deferred, n_skipped);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Submit this boot's DAGs under one `Boot` root: a `Noop` anchor with the
|
||||
/// startup sweep + per-agent reconciles hung off it via `parent_id`, so the
|
||||
/// dashboard renders the boot as a single tree instead of N+1 rows. No-op when
|
||||
/// there's nothing to do. The `parent_id` link is a display grouping, not a
|
||||
/// dependency edge — the children run concurrently, so the reconciles never
|
||||
/// wait behind the lock bump.
|
||||
fn submit_boot_tree(
|
||||
coord: &Arc<Coordinator>,
|
||||
any_stale: bool,
|
||||
fanout: Vec<String>,
|
||||
drifted: Vec<String>,
|
||||
n_deferred: usize,
|
||||
n_skipped: usize,
|
||||
) {
|
||||
// Only emit a boot root when there's actually boot work — a fully-quiet
|
||||
// boot (nothing stale, nothing drifted) submits nothing, exactly as before.
|
||||
let boot_root_id = if any_stale || !drifted.is_empty() {
|
||||
let reason = format!(
|
||||
"boot: {} rebuild(s), {} reconcile(s), {} deferred (offline), {} up-to-date",
|
||||
fanout.len(),
|
||||
drifted.len(),
|
||||
n_deferred,
|
||||
n_skipped,
|
||||
);
|
||||
match coord
|
||||
.job_queue
|
||||
.submit(crate::job_queue::templates::boot_root(reason))
|
||||
{
|
||||
Ok(id) => Some(id),
|
||||
Err(e) => {
|
||||
tracing::warn!(error = ?e, "boot reconcile: boot-root submit failed");
|
||||
None
|
||||
}
|
||||
}
|
||||
} else {
|
||||
None
|
||||
};
|
||||
|
||||
// Sweep whenever ANY marker is stale — even when every stale agent is
|
||||
// wanted-offline: the hyperhive lock bump must land now so their later
|
||||
// start-upgrade rebuilds build against it. No stale agents ⇒ no sweep ⇒ no
|
||||
// meta commit on a no-change boot.
|
||||
if any_stale {
|
||||
let reason = format!(
|
||||
"startup sweep: {} rebuild(s), {} deferred (offline), {} up-to-date",
|
||||
|
|
@ -284,27 +326,24 @@ pub async fn run(coord: Arc<Coordinator>) -> Result<()> {
|
|||
n_deferred,
|
||||
n_skipped,
|
||||
);
|
||||
if let Err(e) = coord
|
||||
.job_queue
|
||||
.submit(crate::job_queue::templates::startup_sweep(reason, fanout))
|
||||
{
|
||||
let mut spec = crate::job_queue::templates::startup_sweep(reason, fanout);
|
||||
spec.parent_id = boot_root_id;
|
||||
if let Err(e) = coord.job_queue.submit(spec) {
|
||||
tracing::warn!(error = ?e, "boot reconcile: sweep submit failed");
|
||||
}
|
||||
}
|
||||
for name in drifted {
|
||||
if let Err(e) = coord
|
||||
.job_queue
|
||||
.submit(crate::job_queue::templates::reconcile_only(
|
||||
crate::job_queue::Template::Reconcile,
|
||||
&name,
|
||||
crate::job_queue::Source::AutoUpdate,
|
||||
"boot reconcile".to_owned(),
|
||||
None,
|
||||
))
|
||||
{
|
||||
let mut spec = crate::job_queue::templates::reconcile_only(
|
||||
crate::job_queue::Template::Reconcile,
|
||||
&name,
|
||||
crate::job_queue::Source::AutoUpdate,
|
||||
"boot reconcile".to_owned(),
|
||||
None,
|
||||
);
|
||||
spec.parent_id = boot_root_id;
|
||||
if let Err(e) = coord.job_queue.submit(spec) {
|
||||
tracing::warn!(%name, error = ?e, "boot reconcile: submit failed");
|
||||
}
|
||||
}
|
||||
coord.emit_rebuild_queue_snapshot();
|
||||
Ok(())
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue