Line data Source code
1 : use std::convert::Infallible;
2 :
3 : use anyhow::bail;
4 : use tokio_util::sync::CancellationToken;
5 : use tracing::{info, warn};
6 :
7 : /// Handle unix signals appropriately.
8 0 : pub async fn handle<F>(
9 0 : token: CancellationToken,
10 0 : mut refresh_config: F,
11 0 : ) -> anyhow::Result<Infallible>
12 0 : where
13 0 : F: FnMut(),
14 0 : {
15 : use tokio::signal::unix::{signal, SignalKind};
16 :
17 0 : let mut hangup = signal(SignalKind::hangup())?;
18 0 : let mut interrupt = signal(SignalKind::interrupt())?;
19 0 : let mut terminate = signal(SignalKind::terminate())?;
20 :
21 : loop {
22 0 : tokio::select! {
23 : // Hangup is commonly used for config reload.
24 0 : _ = hangup.recv() => {
25 0 : info!("received SIGHUP");
26 0 : refresh_config();
27 : }
28 : // Shut down the whole application.
29 0 : _ = interrupt.recv() => {
30 0 : warn!("received SIGINT, exiting immediately");
31 0 : bail!("interrupted");
32 : }
33 0 : _ = terminate.recv() => {
34 0 : warn!("received SIGTERM, shutting down once all existing connections have closed");
35 0 : token.cancel();
36 : }
37 : }
38 : }
39 0 : }
|