codex_memory/application/
lifecycle.rs1use crate::application::DependencyContainer;
2use anyhow::Result;
3use std::sync::Arc;
4use tokio::signal;
5use tracing::{error, info};
6
7pub struct ApplicationLifecycle {
9 container: Arc<DependencyContainer>,
10}
11
12impl ApplicationLifecycle {
13 pub fn new(container: Arc<DependencyContainer>) -> Self {
14 Self { container }
15 }
16
17 pub async fn initialize(&self) -> Result<()> {
19 info!("🚀 Initializing application...");
20
21 self.container.config.validate()?;
23
24 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 pub async fn shutdown(&self) -> Result<()> {
35 info!("🛑 Initiating graceful shutdown...");
36
37 if let Some(ref _harvester) = self.container.harvester_service {
39 }
44
45 if let Some(ref tier_manager) = self.container.tier_manager {
46 tier_manager.stop().await;
48 }
49
50 info!("🎉 Graceful shutdown completed");
51 Ok(())
52 }
53
54 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}