1use std::{collections::HashMap, sync::Arc};
7
8use anyhow::Result;
9use serde::{Deserialize, Serialize};
10use tokio::sync::RwLock;
11use tracing::{debug, info, instrument};
12
13#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
15pub enum LifecycleEvent {
16 Initialize,
18 Start,
20 Stop,
22 Dispose,
24 Reload,
26 Suspend,
28 Resume,
30 Custom(String),
32}
33
34#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
36pub enum LifecycleState {
37 Created,
39 Initializing,
41 Running,
43 Suspending,
45 Suspended,
47 Stopping,
49 Stopped,
51 Disposing,
53 Disposed,
55 Error,
57}
58
59#[allow(dead_code)]
61type LifecycleEventHandler = fn(&str, LifecycleEvent) -> Result<()>;
62
63pub struct LifecycleManager {
65 handlers:Arc<RwLock<HashMap<String, LifecycleHandlerInfo>>>,
67 states:Arc<RwLock<HashMap<String, LifecycleState>>>,
69 event_history:Arc<RwLock<Vec<LifecycleEventRecord>>>,
71}
72
73#[derive(Debug, Clone)]
75struct LifecycleHandlerInfo {
76 #[allow(dead_code)]
78 extension_id:String,
79 state:LifecycleState,
81 #[allow(dead_code)]
83 supported_events:Vec<LifecycleEvent>,
84 last_state_change:Option<u64>,
86}
87
88#[derive(Debug, Clone, Serialize, Deserialize)]
90pub struct LifecycleEventRecord {
91 pub extension_id:String,
93 pub event:LifecycleEvent,
95 pub previous_state:LifecycleState,
97 pub new_state:LifecycleState,
99 pub timestamp:u64,
101 pub duration_ms:u64,
103 pub success:bool,
105 pub error:Option<String>,
107}
108
109impl LifecycleManager {
110 pub fn new() -> Self {
112 Self {
113 handlers:Arc::new(RwLock::new(HashMap::new())),
114 states:Arc::new(RwLock::new(HashMap::new())),
115 event_history:Arc::new(RwLock::new(Vec::new())),
116 }
117 }
118
119 #[instrument(skip(self, extension_id))]
121 pub async fn register_extension(&self, extension_id:&str, initial_state:LifecycleState) -> Result<()> {
122 info!("Registering extension for lifecycle management: {}", extension_id);
123
124 let mut handlers = self.handlers.write().await;
125 handlers.insert(
126 extension_id.to_string(),
127 LifecycleHandlerInfo {
128 extension_id:extension_id.to_string(),
129 state:initial_state,
130 supported_events:vec![
131 LifecycleEvent::Initialize,
132 LifecycleEvent::Start,
133 LifecycleEvent::Stop,
134 LifecycleEvent::Dispose,
135 ],
136 last_state_change:Some(
137 std::time::SystemTime::now()
138 .duration_since(std::time::UNIX_EPOCH)
139 .map(|d| d.as_secs())
140 .unwrap_or(0),
141 ),
142 },
143 );
144
145 let mut states = self.states.write().await;
146 states.insert(extension_id.to_string(), initial_state);
147
148 debug!("Extension registered: {}", extension_id);
149
150 Ok(())
151 }
152
153 #[instrument(skip(self, extension_id))]
155 pub async fn unregister_extension(&self, extension_id:&str) -> Result<()> {
156 info!("Unregistering extension from lifecycle management: {}", extension_id);
157
158 let mut handlers = self.handlers.write().await;
159 handlers.remove(extension_id);
160
161 let mut states = self.states.write().await;
162 states.remove(extension_id);
163
164 debug!("Extension unregistered: {}", extension_id);
165
166 Ok(())
167 }
168
169 pub async fn get_state(&self, extension_id:&str) -> Option<LifecycleState> {
171 self.states.read().await.get(extension_id).copied()
172 }
173
174 #[instrument(skip(self, extension_id, event))]
176 pub async fn transition(&self, extension_id:&str, event:LifecycleEvent) -> Result<LifecycleState> {
177 info!("Transitioning extension {} with event: {:?}", extension_id, event);
178
179 let start = std::time::Instant::now();
180
181 let current_state = self
183 .get_state(extension_id)
184 .await
185 .ok_or_else(|| anyhow::anyhow!("Extension not found: {}", extension_id))?;
186
187 let event_clone = event.clone();
189
190 let new_state = self.determine_next_state(current_state, event)?;
192
193 self.perform_state_transition(extension_id, event_clone.clone(), new_state)
195 .await?;
196
197 let elapsed_ms = start.elapsed().as_millis() as u64;
198
199 let record = LifecycleEventRecord {
201 extension_id:extension_id.to_string(),
202 event:event_clone,
203 previous_state:current_state,
204 new_state,
205 timestamp:std::time::SystemTime::now()
206 .duration_since(std::time::UNIX_EPOCH)
207 .map(|d| d.as_secs())
208 .unwrap_or(0),
209 duration_ms:elapsed_ms,
210 success:true,
211 error:None,
212 };
213
214 self.event_history.write().await.push(record);
215
216 debug!(
217 "Extension {} transitioned from {:?} to {:?} in {}ms",
218 extension_id, current_state, new_state, elapsed_ms
219 );
220
221 Ok(new_state)
222 }
223
224 fn determine_next_state(&self, current_state:LifecycleState, event:LifecycleEvent) -> Result<LifecycleState> {
226 match (current_state, event.clone()) {
227 (LifecycleState::Created, LifecycleEvent::Initialize) => Ok(LifecycleState::Initializing),
228 (LifecycleState::Initializing, LifecycleEvent::Start) => Ok(LifecycleState::Running),
229 (LifecycleState::Running, LifecycleEvent::Suspend) => Ok(LifecycleState::Suspending),
230 (LifecycleState::Suspending, _) => Ok(LifecycleState::Suspended),
231 (LifecycleState::Suspended, LifecycleEvent::Resume) => Ok(LifecycleState::Running),
232 (LifecycleState::Running, LifecycleEvent::Stop) => Ok(LifecycleState::Stopping),
233 (LifecycleState::Stopping, _) => Ok(LifecycleState::Stopped),
234 (LifecycleState::Stopped | LifecycleState::Suspended, LifecycleEvent::Dispose) => {
235 Ok(LifecycleState::Disposing)
236 },
237 (LifecycleState::Disposing, _) => Ok(LifecycleState::Disposed),
238 (LifecycleState::Running, LifecycleEvent::Reload) => Ok(LifecycleState::Running),
239 _ => {
240 Err(anyhow::anyhow!(
241 "Invalid transition from {:?} with event {:?}",
242 current_state,
243 event
244 ))
245 },
246 }
247 }
248
249 async fn perform_state_transition(
251 &self,
252 extension_id:&str,
253 event:LifecycleEvent,
254 new_state:LifecycleState,
255 ) -> Result<()> {
256 debug!(
262 "Performing state transition for extension {}: {:?} -> {:?}",
263 extension_id, event, new_state
264 );
265
266 let mut handlers = self.handlers.write().await;
268 if let Some(handler) = handlers.get_mut(extension_id) {
269 handler.state = new_state;
270 handler.last_state_change = Some(
271 std::time::SystemTime::now()
272 .duration_since(std::time::UNIX_EPOCH)
273 .map(|d| d.as_secs())
274 .unwrap_or(0),
275 );
276 }
277
278 let mut states = self.states.write().await;
279 states.insert(extension_id.to_string(), new_state);
280
281 Ok(())
282 }
283
284 #[instrument(skip(self, extension_id, event))]
286 pub async fn trigger_event(&self, extension_id:&str, event:LifecycleEvent) -> Result<()> {
287 info!("Triggering lifecycle event for {}: {:?}", extension_id, event);
288
289 self.transition(extension_id, event).await?;
290
291 Ok(())
292 }
293
294 pub async fn get_event_history(&self) -> Vec<LifecycleEventRecord> { self.event_history.read().await.clone() }
296
297 pub async fn get_event_history_for_extension(&self, extension_id:&str) -> Vec<LifecycleEventRecord> {
299 self.event_history
300 .read()
301 .await
302 .iter()
303 .filter(|r| r.extension_id == extension_id)
304 .cloned()
305 .collect()
306 }
307
308 pub async fn get_registered_extensions(&self) -> Vec<String> {
310 self.handlers.read().await.keys().cloned().collect()
311 }
312
313 pub async fn get_extensions_in_state(&self, state:LifecycleState) -> Vec<String> {
315 self.states
316 .read()
317 .await
318 .iter()
319 .filter(|(_, s)| *s == &state)
320 .map(|(id, _)| id.clone())
321 .collect()
322 }
323}
324
325impl Default for LifecycleManager {
326 fn default() -> Self { Self::new() }
327}
328
329#[cfg(test)]
330mod tests {
331 use super::*;
332
333 #[test]
334 fn test_lifecycle_state() {
335 assert_eq!(LifecycleState::Created, LifecycleState::Created);
336 assert_eq!(LifecycleState::Running, LifecycleState::Running);
337 assert_ne!(LifecycleState::Created, LifecycleState::Running);
338 }
339
340 #[test]
341 fn test_lifecycle_event() {
342 assert_eq!(LifecycleEvent::Initialize, LifecycleEvent::Initialize);
343 assert_eq!(
344 LifecycleEvent::Custom("test".to_string()),
345 LifecycleEvent::Custom("test".to_string())
346 );
347 }
348
349 #[tokio::test]
350 async fn test_lifecycle_manager_registration() {
351 let manager = LifecycleManager::new();
352 let result = manager.register_extension("test.ext", LifecycleState::Created).await;
353
354 assert!(result.is_ok());
355 assert_eq!(manager.get_state("test.ext").await, Some(LifecycleState::Created));
356 }
357
358 #[tokio::test]
359 async fn test_state_transitions() {
360 let manager = LifecycleManager::new();
361 manager.register_extension("test.ext", LifecycleState::Created).await.unwrap();
362
363 let state = manager.transition("test.ext", LifecycleEvent::Initialize).await.unwrap();
365 assert_eq!(state, LifecycleState::Initializing);
366
367 let state = manager.transition("test.ext", LifecycleEvent::Start).await.unwrap();
369 assert_eq!(state, LifecycleState::Running);
370
371 let state = manager.transition("test.ext", LifecycleEvent::Stop).await.unwrap();
373 assert_eq!(state, LifecycleState::Stopping);
374 }
375}