forge: wire ensure_all() boot-warn sites to the dashboard banner
Adds set_boot_warning() to stats/warnings.rs: a one-shot variant of set_warning() for steps that run once at hive-c0re boot (no periodic retry to observe a later success and clear the banner via WarningGuard drop). It forgets the guard, leaking it for the life of the process — the banner clears on the next hive-c0re restart, which is also when a config/environment fix would take effect. Wires every remaining tracing::warn!()-and-forget site in forge::ensure_all() to also raise a boot warning: core user/token provisioning, per-org seeding, the operators-team grant per org, the core/meta repo, shared docs repo, knowledge repo (+ its local clone), both avatar uploads, and the final nixos-container list failure. Split the core_token.is_some() body of ensure_all() into a new ensure_all_orgs_and_repos() helper to stay under clippy's function-length limit. Deliberately out of scope: sync_agent() (shared with rebuild_agent(), different blast radius) and ci_runner::ensure_ci_runner_registered() (its own retry logic) — matrix::ensure_all() got the same slice-by- slice treatment.
This commit is contained in:
parent
d124dd205a
commit
f378f842ea
2 changed files with 154 additions and 50 deletions
|
|
@ -103,6 +103,23 @@ pub fn snapshot() -> Vec<ServerWarning> {
|
|||
.collect()
|
||||
}
|
||||
|
||||
/// Raise a warning for a one-shot boot-time step that has no periodic
|
||||
/// retry to observe a later success and clear the banner via
|
||||
/// [`WarningGuard`] drop — e.g. a step inside `forge::ensure_all()`,
|
||||
/// which `tokio::spawn`s once at hive-c0re startup and never runs again
|
||||
/// this process. Intentionally **leaks** the guard for the life of the
|
||||
/// process: the banner clears the next time hive-c0re restarts (a fresh
|
||||
/// process starts with an empty registry) and re-runs the step, which is
|
||||
/// exactly when a config/environment fix would take effect anyway.
|
||||
///
|
||||
/// Do not use this for anything that runs periodically or can be
|
||||
/// retried within the same process — hold the [`WarningGuard`] (or use
|
||||
/// [`crate::stats::sweep_health::SweepHealth`]) so a later success can
|
||||
/// actually clear the banner instead of waiting for a restart.
|
||||
pub fn set_boot_warning(kind: &'static str, level: &'static str, message: impl Into<String>) {
|
||||
std::mem::forget(set_warning(kind, level, message));
|
||||
}
|
||||
|
||||
/// RAII handle for one active warning. Drop clears the `kind` from the
|
||||
/// banner. Obtained from [`set_warning`].
|
||||
#[must_use = "dropping the guard immediately clears the warning; bind it for as long as the condition holds"]
|
||||
|
|
@ -237,6 +254,24 @@ mod tests {
|
|||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn boot_warning_survives_without_a_held_guard() {
|
||||
// Unlike `set_warning`, `set_boot_warning` returns nothing to hold —
|
||||
// the whole point is that the warning outlives the call that raised
|
||||
// it (no guard in scope to drop).
|
||||
set_boot_warning("t_boot", "warn", "one-shot step failed");
|
||||
assert_eq!(
|
||||
find("t_boot").map(|w| w.message),
|
||||
Some("one-shot step failed".to_owned())
|
||||
);
|
||||
// A later boot_warning for the same kind still just replaces the
|
||||
// payload (same registry semantics as `set_warning`).
|
||||
set_boot_warning("t_boot", "crit", "still failing");
|
||||
let w = find("t_boot").expect("present");
|
||||
assert_eq!(w.level, "crit");
|
||||
assert_eq!(w.message, "still failing");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn concurrent_same_kind_resolves_to_absent_after_all_drop() {
|
||||
// Many threads contend on ONE kind, each holding its own guard
|
||||
|
|
|
|||
Loading…
Reference in a new issue