apollo_router/router/event/
shutdown.rsuse std::pin::Pin;
use derivative::Derivative;
use derive_more::Display;
use futures::prelude::*;
use crate::router::Event;
use crate::router::Event::Shutdown;
type ShutdownFuture = Pin<Box<dyn Future<Output = ()> + Send>>;
#[derive(Display, Derivative)]
#[derivative(Debug)]
#[non_exhaustive]
pub enum ShutdownSource {
#[display(fmt = "None")]
None,
#[display(fmt = "Custom")]
Custom(#[derivative(Debug = "ignore")] ShutdownFuture),
#[display(fmt = "CtrlC")]
CtrlC,
}
impl ShutdownSource {
pub(crate) fn into_stream(self) -> impl Stream<Item = Event> {
match self {
ShutdownSource::None => stream::pending::<Event>().boxed(),
ShutdownSource::Custom(future) => future.map(|_| Shutdown).into_stream().boxed(),
ShutdownSource::CtrlC => {
#[cfg(not(unix))]
{
async {
tokio::signal::ctrl_c()
.await
.expect("Failed to install CTRL+C signal handler");
}
.map(|_| Shutdown)
.into_stream()
.boxed()
}
#[cfg(unix)]
future::select(
tokio::signal::ctrl_c().map(|s| s.ok()).boxed(),
async {
tokio::signal::unix::signal(tokio::signal::unix::SignalKind::terminate())
.expect("Failed to install SIGTERM signal handler")
.recv()
.await
}
.boxed(),
)
.map(|_| Shutdown)
.into_stream()
.boxed()
}
}
}
}