Ok,
I have a working microservice that provides gRPC via tokio / tonic and exposes metrics via warp. Both http and gRPC services shutdown correctly when receiving a sigint signal i.e. kill via terminal.
Full code on Github, and the relevant code below:
// Sigint signal handler that closes the DB connection upon shutdown
let signal = grpc_sigint(dbm.clone());
// Construct health service for gRPC server
let (mut health_reporter, health_svc) = tonic_health::server::health_reporter();
health_reporter.set_serving::<JobRunnerServer<MyJobRunner>>().await;
// Build gRPC server with health service and signal sigint handler
let grpc_server = TonicServer::builder()
.add_service(grpc_svc)
.add_service(health_svc)
.serve_with_shutdown(grpc_addr, signal);
The sigint handler is fairly basic but gets the job done.
async fn grpc_sigint(dbm: DBManager) {
let _ = signal(SignalKind::terminate())
.expect("failed to create a new SIGINT signal handler for gRPC")
.recv()
.await;
// Shutdown the DB connection.
dbm.close_db().await.expect("Failed to close database connection");
println!("gRPC shutdown complete");
}
This works fine, but the service doesn't capture ctrl-c and doesn't respond to other signals such as sig-quit because it only has one signal handler for sigint. Because the service is supposed to run on multiple platforms, it's not given that sig-int is the only signal to handle.
I did some online search, but somehow most examples were similar to the one I am using so it's not so clear to me how to handle multiple signals in tokio to trigger a graceful shutdown whenever any of the signals fires.
Therefore, my question is, how do you modify the signal handler so that it captures multiple shutdown signals such as sigint, ctr-c or sig-quit?
Thank you in advance.
You claim to listen to
SIGINT
(=Ctrl+C
), butSignalType::terminate()
actually listens toSIGTERM
(=kill
or system shutdown).I'm not sure if listening for
SIGQUIT
is really necessary; in most situationsSIGINT
andSIGTERM
are sufficient.You can of course listen to both, through
tokio::select!()
. Here is an example. The code is taken fromtokio-graceful-shutdown
. (Disclaimer: I'm the author of this crate)