use crate::runtime::lifecycle::{RuntimeControlPlane, RuntimeControlPlaneState, RuntimeExitReport};
use tokio::sync::broadcast;
use tokio::task::JoinHandle;
#[derive(Debug, Clone, Copy)]
pub struct RuntimeWatchdog;
impl RuntimeWatchdog {
pub fn publish_started(
control_plane: RuntimeControlPlane,
event_sender: broadcast::Sender<String>,
) {
control_plane.mark_alive();
let _ignored = event_sender.send("runtime_control_loop_started:startup".to_owned());
}
pub fn spawn(
control_plane: RuntimeControlPlane,
join_handle: JoinHandle<RuntimeExitReport>,
event_sender: broadcast::Sender<String>,
) {
tokio::spawn(async move {
let report = match join_handle.await {
Ok(report) => report,
Err(error) => RuntimeExitReport::failed(
"watchdog",
format!("runtime control loop panic or cancellation: {error}"),
error.is_panic(),
true,
),
};
let report = control_plane.complete(report);
let event_name = match report.state {
RuntimeControlPlaneState::Completed => "runtime_control_loop_completed",
RuntimeControlPlaneState::Failed => "runtime_control_loop_failed",
RuntimeControlPlaneState::Starting
| RuntimeControlPlaneState::Alive
| RuntimeControlPlaneState::ShuttingDown => "runtime_control_loop_unexpected",
};
let _ignored =
event_sender.send(format!("{event_name}:{}:{}", report.phase, report.reason));
});
}
}