codex_memory/application/
lifecycle.rs

1use crate::application::DependencyContainer;
2use anyhow::Result;
3use std::sync::Arc;
4use tokio::signal;
5use tracing::{error, info};
6
7/// Manages application lifecycle events and graceful shutdown
8pub struct ApplicationLifecycle {
9    container: Arc<DependencyContainer>,
10}
11
12impl ApplicationLifecycle {
13    pub fn new(container: Arc<DependencyContainer>) -> Self {
14        Self { container }
15    }
16
17    /// Initialize the application
18    pub async fn initialize(&self) -> Result<()> {
19        info!("🚀 Initializing application...");
20
21        // Validate configuration
22        self.container.config.validate()?;
23
24        // Run health checks
25        if !self.container.health_check().await? {
26            return Err(anyhow::anyhow!("Initial health check failed"));
27        }
28
29        info!("✅ Application initialized successfully");
30        Ok(())
31    }
32
33    /// Graceful shutdown
34    pub async fn shutdown(&self) -> Result<()> {
35        info!("🛑 Initiating graceful shutdown...");
36
37        // Stop all services gracefully
38        if let Some(ref _harvester) = self.container.harvester_service {
39            // TODO: Implement proper stop method
40            // if let Err(e) = harvester.stop().await {
41            //     error!("Error stopping harvester service: {}", e);
42            // }
43        }
44
45        if let Some(ref tier_manager) = self.container.tier_manager {
46            // TierManager stop returns () not Result, so no error handling needed
47            tier_manager.stop().await;
48        }
49
50        info!("🎉 Graceful shutdown completed");
51        Ok(())
52    }
53
54    /// Wait for shutdown signals
55    pub async fn wait_for_shutdown(&self) {
56        let ctrl_c = async {
57            if let Err(e) = signal::ctrl_c().await {
58                error!("Failed to install Ctrl+C handler: {}", e);
59            }
60        };
61
62        #[cfg(unix)]
63        let terminate = async {
64            match signal::unix::signal(signal::unix::SignalKind::terminate()) {
65                Ok(mut stream) => {
66                    stream.recv().await;
67                }
68                Err(e) => {
69                    error!("Failed to install terminate signal handler: {}", e);
70                }
71            }
72        };
73
74        #[cfg(not(unix))]
75        let terminate = std::future::pending::<()>();
76
77        tokio::select! {
78            _ = ctrl_c => {},
79            _ = terminate => {},
80        }
81
82        info!("Shutdown signal received");
83    }
84}