mirror of
https://github.com/neondatabase/neon.git
synced 2026-05-14 19:50:38 +00:00
Service targeted for storing and retrieving LFC prewarm data. Can be used for proxying S3 access for Postgres extensions like pg_mooncake as well. Requests must include a Bearer JWT token. Token is validated using a pemfile (should be passed in infra/). Note: app is not tolerant to extra trailing slashes, see app.rs `delete_prefix` test for comments. Resolves: https://github.com/neondatabase/cloud/issues/26342 Unrelated changes: gate a `rename_noreplace` feature and disable it in `remote_storage` so as `object_storage` can be built with musl
68 lines
2.0 KiB
Rust
68 lines
2.0 KiB
Rust
pub use signal_hook::consts::TERM_SIGNALS;
|
|
pub use signal_hook::consts::signal::*;
|
|
use signal_hook::iterator::Signals;
|
|
use tokio::signal::unix::{SignalKind, signal};
|
|
use tracing::info;
|
|
|
|
pub enum Signal {
|
|
Quit,
|
|
Interrupt,
|
|
Terminate,
|
|
}
|
|
|
|
impl Signal {
|
|
pub fn name(&self) -> &'static str {
|
|
match self {
|
|
Signal::Quit => "SIGQUIT",
|
|
Signal::Interrupt => "SIGINT",
|
|
Signal::Terminate => "SIGTERM",
|
|
}
|
|
}
|
|
}
|
|
|
|
pub struct ShutdownSignals;
|
|
|
|
impl ShutdownSignals {
|
|
pub fn handle(mut handler: impl FnMut(Signal) -> anyhow::Result<()>) -> anyhow::Result<()> {
|
|
for raw_signal in Signals::new(TERM_SIGNALS)?.into_iter() {
|
|
let signal = match raw_signal {
|
|
SIGINT => Signal::Interrupt,
|
|
SIGTERM => Signal::Terminate,
|
|
SIGQUIT => Signal::Quit,
|
|
other => panic!("unknown signal: {}", other),
|
|
};
|
|
|
|
handler(signal)?;
|
|
}
|
|
|
|
Ok(())
|
|
}
|
|
}
|
|
|
|
/// Runs in a loop since we want to be responsive to multiple signals
|
|
/// even after triggering shutdown (e.g. a SIGQUIT after a slow SIGTERM shutdown)
|
|
/// <https://github.com/neondatabase/neon/issues/9740>
|
|
pub async fn signal_handler(token: tokio_util::sync::CancellationToken) {
|
|
let mut sigint = signal(SignalKind::interrupt()).unwrap();
|
|
let mut sigterm = signal(SignalKind::terminate()).unwrap();
|
|
let mut sigquit = signal(SignalKind::quit()).unwrap();
|
|
|
|
loop {
|
|
let signal = tokio::select! {
|
|
_ = sigquit.recv() => {
|
|
info!("Got signal SIGQUIT. Terminating in immediate shutdown mode.");
|
|
std::process::exit(111);
|
|
}
|
|
_ = sigint.recv() => "SIGINT",
|
|
_ = sigterm.recv() => "SIGTERM",
|
|
};
|
|
|
|
if !token.is_cancelled() {
|
|
info!("Got signal {signal}. Terminating gracefully in fast shutdown mode.");
|
|
token.cancel();
|
|
} else {
|
|
info!("Got signal {signal}. Already shutting down.");
|
|
}
|
|
}
|
|
}
|