@@ -52,6 +52,15 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
5252 "--public" => {
5353 config. host = "0.0.0.0" . to_string ( ) ;
5454 }
55+ "--db" => {
56+ if i + 1 < args. len ( ) {
57+ config. db_path = Some ( args[ i + 1 ] . clone ( ) ) ;
58+ i += 1 ;
59+ }
60+ }
61+ "--memory" => {
62+ config. db_path = Some ( ":memory:" . to_string ( ) ) ;
63+ }
5564 "--help" => {
5665 print_help ( ) ;
5766 return Ok ( ( ) ) ;
@@ -72,10 +81,24 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
7281 p2p
7382 } ;
7483
84+ // Resolve the snapshot directory for Ineru persistence
85+ let snapshot_dir = match & config. db_path {
86+ Some ( p) if p == ":memory:" => None ,
87+ Some ( p) => std:: path:: Path :: new ( p) . parent ( ) . map ( |p| p. to_path_buf ( ) ) ,
88+ None => {
89+ let home = dirs:: home_dir ( ) . unwrap_or_else ( || std:: path:: PathBuf :: from ( "." ) ) ;
90+ Some ( home. join ( ".aingle" ) . join ( "cortex" ) )
91+ }
92+ } ;
93+
7594 // Create and run server
7695 #[ allow( unused_mut) ]
7796 let mut server = CortexServer :: new ( config) ?;
7897
98+ // Keep a reference to the state for shutdown flush
99+ let state_for_shutdown = server. state ( ) . clone ( ) ;
100+ let snapshot_dir_for_shutdown = snapshot_dir. clone ( ) ;
101+
79102 // Start P2P manager if enabled.
80103 #[ cfg( feature = "p2p" ) ]
81104 if p2p_config. enabled {
@@ -96,12 +119,39 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
96119 }
97120 }
98121
99- // Set up graceful shutdown
100- let shutdown_signal = async {
101- tokio:: signal:: ctrl_c ( )
122+ // Set up graceful shutdown with data flush (handles both SIGINT and SIGTERM)
123+ let shutdown_signal = async move {
124+ let ctrl_c = tokio:: signal:: ctrl_c ( ) ;
125+
126+ #[ cfg( unix) ]
127+ let terminate = async {
128+ tokio:: signal:: unix:: signal ( tokio:: signal:: unix:: SignalKind :: terminate ( ) )
129+ . expect ( "Failed to install SIGTERM handler" )
130+ . recv ( )
131+ . await ;
132+ } ;
133+
134+ #[ cfg( not( unix) ) ]
135+ let terminate = std:: future:: pending :: < ( ) > ( ) ;
136+
137+ tokio:: select! {
138+ _ = ctrl_c => {
139+ tracing:: info!( "SIGINT received — flushing data..." ) ;
140+ }
141+ _ = terminate => {
142+ tracing:: info!( "SIGTERM received — flushing data..." ) ;
143+ }
144+ }
145+
146+ // Flush graph database and save Ineru snapshot
147+ if let Err ( e) = state_for_shutdown
148+ . flush ( snapshot_dir_for_shutdown. as_deref ( ) )
102149 . await
103- . expect ( "Failed to install CTRL+C handler" ) ;
104- tracing:: info!( "Shutdown signal received" ) ;
150+ {
151+ tracing:: error!( "Failed to flush data on shutdown: {}" , e) ;
152+ } else {
153+ tracing:: info!( "Data flushed successfully" ) ;
154+ }
105155 } ;
106156
107157 server. run_with_shutdown ( shutdown_signal) . await ?;
@@ -119,6 +169,8 @@ fn print_help() {
119169 println ! ( " -h, --host <HOST> Host to bind to (default: 127.0.0.1)" ) ;
120170 println ! ( " -p, --port <PORT> Port to listen on (default: 8080)" ) ;
121171 println ! ( " --public Bind to all interfaces (0.0.0.0)" ) ;
172+ println ! ( " --db <PATH> Path to graph database (default: ~/.aingle/cortex/graph.sled)" ) ;
173+ println ! ( " --memory Use volatile in-memory storage (no persistence)" ) ;
122174 println ! ( " -V, --version Print version and exit" ) ;
123175 println ! ( " --help Print this help message" ) ;
124176 println ! ( ) ;
0 commit comments