From 18805b565ab838bc034b54eddb0572d87db5a61c Mon Sep 17 00:00:00 2001 From: bellman Date: Fri, 15 May 2026 09:45:29 +0900 Subject: [PATCH] omx(team): auto-checkpoint worker-2 [2] --- rust/crates/runtime/src/plugin_lifecycle.rs | 59 +++++++++++++++++++++ 1 file changed, 59 insertions(+) diff --git a/rust/crates/runtime/src/plugin_lifecycle.rs b/rust/crates/runtime/src/plugin_lifecycle.rs index bd123219..67d435e3 100644 --- a/rust/crates/runtime/src/plugin_lifecycle.rs +++ b/rust/crates/runtime/src/plugin_lifecycle.rs @@ -61,6 +61,25 @@ pub enum PluginState { } impl PluginState { + #[must_use] + pub fn startup_event(&self) -> Option { + match self { + Self::Healthy => Some(PluginLifecycleEvent::StartupHealthy), + Self::Degraded { .. } => Some(PluginLifecycleEvent::StartupDegraded), + Self::Failed { .. } => Some(PluginLifecycleEvent::StartupFailed), + Self::Unconfigured + | Self::Validated + | Self::Starting + | Self::ShuttingDown + | Self::Stopped => None, + } + } + + #[must_use] + pub fn is_startup_terminal(&self) -> bool { + self.startup_event().is_some() + } + #[must_use] pub fn from_servers(servers: &[ServerHealth]) -> Self { if servers.is_empty() { @@ -122,6 +141,11 @@ pub struct PluginHealthcheck { } impl PluginHealthcheck { + #[must_use] + pub fn startup_event(&self) -> Option { + self.state.startup_event() + } + #[must_use] pub fn new(plugin_name: impl Into, servers: Vec) -> Self { let state = PluginState::from_servers(&servers); @@ -343,6 +367,41 @@ mod tests { } } + #[test] + fn startup_event_maps_terminal_health_states() { + // given + let healthy = + PluginHealthcheck::new("healthy-plugin", vec![healthy_server("alpha", &["search"])]); + let degraded = PluginHealthcheck::new( + "degraded-plugin", + vec![ + healthy_server("alpha", &["search"]), + failed_server("beta", &["write"], "connection refused"), + ], + ); + let failed = PluginHealthcheck::new( + "failed-plugin", + vec![failed_server("beta", &["write"], "connection refused")], + ); + + // then + assert_eq!( + healthy.startup_event(), + Some(PluginLifecycleEvent::StartupHealthy) + ); + assert_eq!( + degraded.startup_event(), + Some(PluginLifecycleEvent::StartupDegraded) + ); + assert_eq!( + failed.startup_event(), + Some(PluginLifecycleEvent::StartupFailed) + ); + assert!(healthy.state.is_startup_terminal()); + assert_eq!(PluginState::Starting.startup_event(), None); + assert!(!PluginState::Starting.is_startup_terminal()); + } + #[test] fn full_lifecycle_happy_path() { // given