Skip to content

Commit 138634e

Browse files
authored
Add signal handler and shutdown hook (#232)
When the application is running in a container, it is given PID 1 which means it does not automatically get given signal handlers and can't be killed. When running the container in the foreground this stops Ctrl-C from interrupting it while in kubernetes it means the graceful shutdown always times out resulting in the container eventually being forcibly deleted, killing the process. Adding an explicit handler for the common signals used to interrupt processes means that Ctrl-C, kubernetes and `podman stop` all work as expected.
1 parent 2800800 commit 138634e

File tree

1 file changed

+15
-0
lines changed

1 file changed

+15
-0
lines changed

src/graphql/mod.rs

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,8 @@ use axum_extra::TypedHeader;
3636
use chrono::{Datelike, Local};
3737
use derive_more::{Display, Error};
3838
use tokio::net::TcpListener;
39+
use tokio::select;
40+
use tokio::signal::unix::{signal, SignalKind};
3941
use tracing::{debug, info, instrument, trace, warn};
4042

4143
use crate::build_info::ServerStatus;
@@ -95,10 +97,23 @@ pub async fn serve_graphql(opts: ServeOptions) {
9597
.await
9698
.unwrap_or_else(|e| panic!("Could not listen on {:?}:{}: {e}", addr.0, addr.1));
9799
axum::serve(listener, app)
100+
.with_graceful_shutdown(create_signal_handler())
98101
.await
99102
.expect("Can't serve graphql endpoint");
100103
}
101104

105+
async fn create_signal_handler() {
106+
let mut term = signal(SignalKind::terminate()).expect("Failed to create SIGTERM listener");
107+
let mut int = signal(SignalKind::interrupt()).expect("Failed to create SIGINT listener");
108+
let mut quit = signal(SignalKind::quit()).expect("Failed to create SIGQUIT listener");
109+
let sig = select! {
110+
_ = term.recv() => "SIGTERM",
111+
_ = int.recv() => "SIGINT",
112+
_ = quit.recv() => "SIGQUIT",
113+
};
114+
info!("Server interrupted by {sig}");
115+
}
116+
102117
pub fn graphql_schema<W: Write>(mut out: W) -> Result<(), std::io::Error> {
103118
let schema = Schema::new(Query, Mutation, EmptySubscription);
104119
write!(out, "{}", schema.sdl())

0 commit comments

Comments
 (0)