diff --git a/NEXT_CHANGELOG.md b/NEXT_CHANGELOG.md index ab206de188..7a8fa5b443 100644 --- a/NEXT_CHANGELOG.md +++ b/NEXT_CHANGELOG.md @@ -54,6 +54,13 @@ Example of logs in JSON: By [@bnjjj](https://github.com/bnjjj) in https://github.com/apollographql/router/pull/1982 +### Reload the configuration when receiving the SIGHUP signal [Issue #35](https://github.com/apollographql/router/issues/35)) + +This adds support for reloading configuration when receiving the SIGHUP signal. This only works on unix-like platforms, +and only with the configuration file. + +By [@Geal](https://github.com/Geal) in https://github.com/apollographql/router/pull/2015 + ## 🐛 Fixes ### Fix the deduplication logic in deduplication caching [Issue #1984](https://github.com/apollographql/router/issues/1984)) diff --git a/apollo-router/src/router.rs b/apollo-router/src/router.rs index db6ff01c0c..b671274241 100644 --- a/apollo-router/src/router.rs +++ b/apollo-router/src/router.rs @@ -318,10 +318,49 @@ impl ConfigurationSource { .boxed() } else { match ConfigurationSource::read_config(&path) { - Ok(configuration) => stream::once(future::ready(UpdateConfiguration( - Box::new(configuration), - ))) - .boxed(), + Ok(configuration) => { + #[cfg(any(test, not(unix)))] + { + stream::once(future::ready(UpdateConfiguration(Box::new( + configuration, + )))) + .boxed() + } + + #[cfg(all(not(test), unix))] + { + let mut sighup_stream = tokio::signal::unix::signal( + tokio::signal::unix::SignalKind::hangup(), + ) + .expect("Failed to install SIGHUP signal handler"); + + let (mut tx, rx) = futures::channel::mpsc::channel(1); + tokio::task::spawn(async move { + while let Some(()) = sighup_stream.recv().await { + tx.send(()).await.unwrap(); + } + }); + futures::stream::select( + stream::once(future::ready(UpdateConfiguration(Box::new( + configuration, + )))) + .boxed(), + rx.filter_map( + move |()| match ConfigurationSource::read_config(&path) { + Ok(configuration) => future::ready(Some( + UpdateConfiguration(Box::new(configuration)), + )), + Err(err) => { + tracing::error!("{}", err); + future::ready(None) + } + }, + ) + .boxed(), + ) + .boxed() + } + } Err(err) => { tracing::error!("{}", err); stream::empty().boxed()