hive-c0re: graceful agent stop — quiesce harness, flush state, then stop

This commit is contained in:
damocles 2026-06-19 08:43:08 +02:00 committed by mara
commit 03ea5d601b
8 changed files with 202 additions and 2 deletions

View file

@ -125,6 +125,12 @@ pub struct Coordinator {
/// the dashboard's `agents_crashing` banner warning via
/// `recent_crash_counts`, which prunes entries older than its window.
recent_crashes: Mutex<HashMap<String, Vec<std::time::Instant>>>,
/// Agents with a graceful stop in progress. Set by the `GracefulStop`
/// orchestration; read by `agent_server::handle_recv`, which returns
/// `Response::GracefulStop` (instead of polling the broker) while an
/// agent is in this set — the inbound fence. Cleared when the agent
/// reports `GracefulStopComplete` or the container is stopped.
graceful_stop_pending: Mutex<HashSet<String>>,
/// Unified wire-facing event channel feeding the dashboard SSE
/// stream. Carries broker messages (mirrored from `broker.subscribe`
/// by the forwarder task in `main.rs`) and dashboard-only mutation
@ -450,6 +456,7 @@ impl Coordinator {
transient: Mutex::new(HashMap::new()),
recent_transient: Mutex::new(HashMap::new()),
recent_crashes: Mutex::new(HashMap::new()),
graceful_stop_pending: Mutex::new(HashSet::new()),
dashboard_events,
event_seq: AtomicU64::new(0),
meta_updates_active: AtomicU64::new(0),
@ -1128,6 +1135,28 @@ impl Coordinator {
}
}
/// Mark `name` as having a graceful stop in progress. While set,
/// `agent_server::handle_recv` returns `Response::GracefulStop` for
/// this agent instead of polling the broker (the inbound fence).
pub fn mark_graceful_stop(&self, name: &str) {
self.graceful_stop_pending
.lock()
.unwrap()
.insert(name.to_owned());
}
/// Whether a graceful stop is pending for `name`.
#[must_use]
pub fn is_graceful_stop_pending(&self, name: &str) -> bool {
self.graceful_stop_pending.lock().unwrap().contains(name)
}
/// Clear the graceful-stop flag for `name` (agent reported
/// `GracefulStopComplete`, or the stop finished / was abandoned).
pub fn clear_graceful_stop(&self, name: &str) {
self.graceful_stop_pending.lock().unwrap().remove(name);
}
/// Set of agents whose transient was cleared within the last
/// `grace` seconds — i.e. agents the operator just acted on,
/// whose stop the crash watcher should NOT classify as a crash.