Skip to main content

appcore_supervisor/
health.rs

1// =============================================================================
2//        #######
3//     ###       ###     F: health.rs
4//    ##   ## ##   ##    P: AppCore-Runtime
5//         ## ##
6//                       C: 2026/07/24 11:51:10 by dnettoRaw
7//    ##   ## ##   ##    U: 2026/07/24 13:18:47 by dnettoRaw
8//      ###########      S: 1.0.1-rc.8
9// =============================================================================
10
11//! Stable health, activation, dependency, and runtime states.
12
13/// Observable health of one managed service.
14#[derive(Debug, Clone, Copy, PartialEq, Eq)]
15pub enum ServiceHealth {
16    /// Startup completed and the service can accept work.
17    Ready,
18    /// The service is running within its declared health policy.
19    Healthy,
20    /// The service remains available with reduced guarantees.
21    Degraded,
22    /// The service cannot provide its responsibility.
23    Failed,
24    /// Service startup is in progress.
25    Starting,
26    /// Cooperative shutdown is in progress.
27    Stopping,
28    /// The service has not produced a trustworthy health signal.
29    Unknown,
30}
31
32impl ServiceHealth {
33    /// Reports whether a compatibility dependency may use this service.
34    pub fn dependency_ready(self) -> bool {
35        matches!(self, Self::Ready | Self::Healthy | Self::Degraded)
36    }
37
38    /// Reports whether the service is in a failed state.
39    pub fn is_failed(self) -> bool {
40        self == Self::Failed
41    }
42}
43
44/// Installation-level activation of one managed service.
45#[derive(Debug, Clone, Copy, PartialEq, Eq)]
46pub enum ServiceActivationState {
47    /// The service is configured and participates in lifecycle management.
48    Enabled,
49    /// The service is intentionally disabled by deployment policy.
50    Disabled,
51    /// The deployment has no provider or configuration for the service.
52    NotConfigured,
53}
54
55impl ServiceActivationState {
56    /// Reports whether lifecycle actions may run for this service.
57    pub fn is_enabled(self) -> bool {
58        self == Self::Enabled
59    }
60
61    /// Reports whether deployment configuration exists for this service.
62    pub fn is_configured(self) -> bool {
63        self != Self::NotConfigured
64    }
65}
66
67/// Concrete execution state of one managed service.
68#[derive(Debug, Clone, Copy, PartialEq, Eq)]
69pub enum ServiceRuntimeState {
70    /// Startup is in progress.
71    Starting,
72    /// The service currently owns its declared resource.
73    Running,
74    /// Cooperative stop was requested.
75    StopRequested,
76    /// Shutdown is in progress.
77    Stopping,
78    /// No service instance owns the resource.
79    Stopped,
80    /// A restart has been scheduled.
81    RestartScheduled,
82    /// A restart worker is executing lifecycle actions.
83    Restarting,
84    /// A previous instance outlived its shutdown timeout.
85    Orphaned,
86    /// Automatic lifecycle actions are disabled pending operator action.
87    Quarantined,
88    /// The service failed without a live orphan.
89    Failed,
90}
91
92impl ServiceRuntimeState {
93    /// Reports whether the service may still own an external resource.
94    pub fn owns_resource(self) -> bool {
95        matches!(
96            self,
97            Self::Starting
98                | Self::Running
99                | Self::StopRequested
100                | Self::Stopping
101                | Self::Restarting
102                | Self::Orphaned
103        )
104    }
105}
106
107/// Minimum health accepted from a declared dependency.
108#[derive(Debug, Clone, Copy, PartialEq, Eq)]
109pub enum DependencyRequirement {
110    /// Accept a dependency that is ready or healthy.
111    Ready,
112    /// Require a steady healthy dependency.
113    Healthy,
114    /// Permit ready, healthy, or explicitly degraded operation.
115    DegradedAllowed,
116    /// Never block the dependent when this dependency is absent or unhealthy.
117    Optional,
118}
119
120impl DependencyRequirement {
121    /// Reports whether `health` satisfies this requirement.
122    pub fn accepts(self, health: ServiceHealth) -> bool {
123        match self {
124            Self::Ready => matches!(health, ServiceHealth::Ready | ServiceHealth::Healthy),
125            Self::Healthy => health == ServiceHealth::Healthy,
126            Self::DegradedAllowed => health.dependency_ready(),
127            Self::Optional => true,
128        }
129    }
130}