Skip to main content

appcore_core/
lifecycle.rs

1// =============================================================================
2//        #######
3//     ###       ###     F: lifecycle.rs
4//    ##   ## ##   ##    P: AppCore-Runtime
5//         ## ##
6//                       C: 2026/05/29 20:47:35 by dnettoRaw
7//    ##   ## ##   ##    U: 2026/07/24 16:07:49 by dnettoRaw
8//      ###########      S: 1.0.1-rc.8
9// =============================================================================
10
11//! Bounded/thread-safe runtime lifecycle with a total enum transition function.
12
13use crate::error::{RuntimeError, RuntimeResult};
14use parking_lot::Mutex;
15
16// NOTA: Estados de lifecycle estendidos como checking-identity, discovering-peers, readonly e syncing
17// foram adiados para a versão v0.7 para manter a estabilidade do contrato de transições por enquanto.
18/// Stable process lifecycle state.
19#[derive(Debug, Clone, Copy, PartialEq, Eq)]
20pub enum RuntimeLifecycleState {
21    /// Runtime process is booting.
22    Booting,
23    /// Runtime configuration is being loaded.
24    LoadingConfig,
25    /// Security configuration is being checked.
26    CheckingSecurity,
27    /// Storage boundaries are being opened.
28    OpeningStorage,
29    /// Runtime API boundaries are starting.
30    StartingApi,
31    /// Runtime is accepting declared work.
32    Running,
33    /// Runtime remains available with reduced guarantees.
34    Degraded,
35    /// Runtime accepts only explicitly permitted operations.
36    Restricted,
37    /// Runtime is performing graceful shutdown.
38    ShuttingDown,
39    /// Runtime has stopped.
40    Stopped,
41}
42
43/// Event accepted by the Runtime process lifecycle.
44#[derive(Debug, Clone, Copy, PartialEq, Eq)]
45pub enum RuntimeLifecycleEvent {
46    /// Configuration loading completed.
47    ConfigLoaded,
48    /// Security checks completed.
49    SecurityChecked,
50    /// Storage initialization completed.
51    StorageOpened,
52    /// API startup completed.
53    ApiStarted,
54    /// A degradable failure was observed.
55    DegradedDetected,
56    /// A restriction policy was activated.
57    RestrictedDetected,
58    /// Graceful shutdown was requested.
59    ShutdownRequested,
60    /// Graceful shutdown completed.
61    ShutdownCompleted,
62    /// A degraded or restricted condition recovered.
63    RecoveryCompleted,
64}
65
66/// Thread-safe state machine for the Runtime process lifecycle.
67#[derive(Debug)]
68pub struct RuntimeLifecycle {
69    state: Mutex<RuntimeLifecycleState>,
70}
71
72impl Clone for RuntimeLifecycle {
73    fn clone(&self) -> Self {
74        let state = *self.state.lock();
75        Self {
76            state: Mutex::new(state),
77        }
78    }
79}
80
81const fn next_state(
82    state: RuntimeLifecycleState,
83    event: RuntimeLifecycleEvent,
84) -> Option<RuntimeLifecycleState> {
85    match (state, event) {
86        (RuntimeLifecycleState::Booting, RuntimeLifecycleEvent::ConfigLoaded) => {
87            Some(RuntimeLifecycleState::CheckingSecurity)
88        }
89        (RuntimeLifecycleState::CheckingSecurity, RuntimeLifecycleEvent::SecurityChecked) => {
90            Some(RuntimeLifecycleState::OpeningStorage)
91        }
92        (RuntimeLifecycleState::OpeningStorage, RuntimeLifecycleEvent::StorageOpened) => {
93            Some(RuntimeLifecycleState::StartingApi)
94        }
95        (RuntimeLifecycleState::StartingApi, RuntimeLifecycleEvent::ApiStarted) => {
96            Some(RuntimeLifecycleState::Running)
97        }
98        (RuntimeLifecycleState::Running, RuntimeLifecycleEvent::DegradedDetected) => {
99            Some(RuntimeLifecycleState::Degraded)
100        }
101        (RuntimeLifecycleState::Running, RuntimeLifecycleEvent::RestrictedDetected) => {
102            Some(RuntimeLifecycleState::Restricted)
103        }
104        (
105            RuntimeLifecycleState::Degraded | RuntimeLifecycleState::Restricted,
106            RuntimeLifecycleEvent::RecoveryCompleted,
107        ) => Some(RuntimeLifecycleState::Running),
108        (
109            RuntimeLifecycleState::Running
110            | RuntimeLifecycleState::Degraded
111            | RuntimeLifecycleState::Restricted,
112            RuntimeLifecycleEvent::ShutdownRequested,
113        ) => Some(RuntimeLifecycleState::ShuttingDown),
114        (RuntimeLifecycleState::ShuttingDown, RuntimeLifecycleEvent::ShutdownCompleted) => {
115            Some(RuntimeLifecycleState::Stopped)
116        }
117        _ => None,
118    }
119}
120
121impl RuntimeLifecycle {
122    /// Creates a lifecycle in the booting state with all valid transitions.
123    pub fn new() -> Self {
124        Self {
125            state: Mutex::new(RuntimeLifecycleState::Booting),
126        }
127    }
128
129    /// Returns the current lifecycle state.
130    pub fn current(&self) -> RuntimeLifecycleState {
131        *self.state.lock()
132    }
133
134    /// Applies one lifecycle event and returns the resulting state.
135    pub fn apply(&self, event: RuntimeLifecycleEvent) -> RuntimeResult<RuntimeLifecycleState> {
136        let mut state = self.state.lock();
137        let next = next_state(*state, event).ok_or(RuntimeError::InvalidStateTransition)?;
138        *state = next;
139        Ok(next)
140    }
141
142    /// Reports whether the lifecycle is in the normal running state.
143    pub fn is_running(&self) -> bool {
144        self.current() == RuntimeLifecycleState::Running
145    }
146
147    /// Reports whether shutdown has completed.
148    pub fn is_stopped(&self) -> bool {
149        self.current() == RuntimeLifecycleState::Stopped
150    }
151
152    /// Reports whether restricted operation is active.
153    pub fn is_restricted(&self) -> bool {
154        self.current() == RuntimeLifecycleState::Restricted
155    }
156}
157
158impl Default for RuntimeLifecycle {
159    fn default() -> Self {
160        Self::new()
161    }
162}
163
164#[cfg(test)]
165#[path = "lifecycle_tests.rs"]
166mod tests;