Skip to content

Commit 08e793d

Browse files
authored
Merge pull request #1 from hotdata-dev/feat/graceful-shutdown
feat(server): add graceful shutdown handling
2 parents 9653173 + ce80a5f commit 08e793d

File tree

2 files changed

+42
-2
lines changed

2 files changed

+42
-2
lines changed

src/bin/server.rs

Lines changed: 38 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ async fn main() -> Result<()> {
4040

4141
// Create router
4242
let app = AppServer::new(engine);
43+
let engine = app.engine.clone();
4344

4445
// Create server address
4546
let addr = format!("{}:{}", config.server.host, config.server.port);
@@ -49,7 +50,43 @@ async fn main() -> Result<()> {
4950
tracing::info!("Server listening on {}", addr);
5051

5152
// Start server
52-
axum::serve(listener, app.router).await?;
53+
let server = axum::serve(listener, app.router)
54+
.with_graceful_shutdown(shutdown());
55+
56+
server.await?;
57+
58+
// Explicitly shutdown engine to close catalog connection
59+
if let Err(e) = engine.shutdown() {
60+
tracing::error!("Error during engine shutdown: {}", e);
61+
}
62+
63+
tracing::info!("Server shutdown complete");
5364

5465
Ok(())
5566
}
67+
68+
async fn shutdown() {
69+
let ctrl_c = async {
70+
tokio::signal::ctrl_c()
71+
.await
72+
.expect("failed to install Ctrl+C handler");
73+
};
74+
75+
#[cfg(unix)]
76+
let terminate = async {
77+
tokio::signal::unix::signal(tokio::signal::unix::SignalKind::terminate())
78+
.expect("failed to install signal handler")
79+
.recv()
80+
.await;
81+
};
82+
83+
#[cfg(not(unix))]
84+
let terminate = std::future::pending::<()>();
85+
86+
tokio::select! {
87+
_ = ctrl_c => {},
88+
_ = terminate => {},
89+
}
90+
91+
tracing::info!("Shutdown signal received, stopping server...");
92+
}

src/http/app_server.rs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ use std::sync::Arc;
99

1010
pub struct AppServer {
1111
pub router: Router,
12+
pub engine: Arc<HotDataEngine>,
1213
}
1314

1415
pub const PATH_QUERY: &str = "/query";
@@ -18,6 +19,7 @@ pub const PATH_CONNECTIONS: &str = "/connections";
1819

1920
impl AppServer {
2021
pub fn new(engine: HotDataEngine) -> Self {
22+
let engine = Arc::new(engine);
2123
AppServer {
2224
router: Router::new()
2325
.route(PATH_QUERY, post(query_handler))
@@ -27,7 +29,8 @@ impl AppServer {
2729
PATH_CONNECTIONS,
2830
post(create_connection_handler).get(list_connections_handler),
2931
)
30-
.with_state(Arc::new(engine)),
32+
.with_state(engine.clone()),
33+
engine,
3134
}
3235
}
3336
}

0 commit comments

Comments
 (0)