Fix handling of SIGTERM on *nix (#178)

* Fix handling of SIGTERM on *nix

This is just for future extensibility

* Fix error codes

I have been silly enough to break error codes
next
Sayan 3 years ago committed by GitHub
parent 5be3041138
commit d53a0cb505
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -10,6 +10,8 @@ All changes in this project will be noted in this file.
- More than one process can no longer concurrently use the same data directory, preventing any possible data corruption [see [#169](https://github.com/skytable/skytable/pull/169), [#167](https://github.com/skytable/skytable/issues/167)] - More than one process can no longer concurrently use the same data directory, preventing any possible data corruption [see [#169](https://github.com/skytable/skytable/pull/169), [#167](https://github.com/skytable/skytable/issues/167)]
- Fixed longstanding error in `sky-bench` component that caused key collisions - Fixed longstanding error in `sky-bench` component that caused key collisions
- Fixed bug in `sky-bench` that allowed passing 0 for the inputs - Fixed bug in `sky-bench` that allowed passing 0 for the inputs
- Fixed handling of SIGTERM in `skyd` [see [#178](https://github.com/skytable/skytable/pull/178)]
- Fixed incorrect termination codes [see [#178](https://github.com/skytable/skytable/pull/178)]
### Additions ### Additions

@ -54,7 +54,7 @@ pub async fn start_repl() {
Ok(p) => p, Ok(p) => p,
Err(_) => { Err(_) => {
eprintln!("ERROR: Invalid port"); eprintln!("ERROR: Invalid port");
process::exit(0x100); process::exit(0x01);
} }
}, },
None => 2003, None => 2003,
@ -63,7 +63,7 @@ pub async fn start_repl() {
Ok(c) => c, Ok(c) => c,
Err(e) => { Err(e) => {
eprintln!("ERROR: {}", e); eprintln!("ERROR: {}", e);
process::exit(0x100); process::exit(0x01);
} }
}; };
let mut runner = Runner::new(con); let mut runner = Runner::new(con);

@ -46,7 +46,7 @@ where
match self { match self {
Self::Err(e) => { Self::Err(e) => {
log::error!("{} : '{}'", msg.to_string(), e); log::error!("{} : '{}'", msg.to_string(), e);
std::process::exit(0x100); std::process::exit(0x01);
} }
Self::Ok(v) => v, Self::Ok(v) => v,
} }
@ -61,7 +61,7 @@ impl<T> ExitError<T> for Option<T> {
match self { match self {
Self::None => { Self::None => {
log::error!("{}", msg.to_string()); log::error!("{}", msg.to_string());
std::process::exit(0x100); std::process::exit(0x01);
} }
Self::Some(v) => v, Self::Some(v) => v,
} }

@ -422,7 +422,7 @@ pub fn get_config_file_or_return_cfg() -> Result<ConfigType<ParsedConfig, String
if let Some(format) = matches.value_of("format") { if let Some(format) = matches.value_of("format") {
if let Err(e) = compat::upgrade(format) { if let Err(e) = compat::upgrade(format) {
log::error!("Dataset upgrade failed with error: {}", e); log::error!("Dataset upgrade failed with error: {}", e);
process::exit(0x100); process::exit(0x01);
} else { } else {
process::exit(0x000); process::exit(0x000);
} }

@ -246,6 +246,34 @@ impl MultiListener {
} }
} }
#[cfg(unix)]
use core::{pin::Pin, task::Context, task::Poll};
#[cfg(unix)]
use tokio::signal::unix::{signal as fnsignal, Signal, SignalKind};
#[cfg(unix)]
/// Object to bind to unix-specific signals
pub struct UnixTerminationSignal {
sigterm: Signal,
}
#[cfg(unix)]
impl UnixTerminationSignal {
pub fn init() -> Result<Self, String> {
let sigterm = fnsignal(SignalKind::terminate())
.map_err(|e| format!("Failed to bind to signal with: {}", e))?;
Ok(Self { sigterm })
}
}
#[cfg(unix)]
impl Future for UnixTerminationSignal {
type Output = Option<()>;
fn poll(mut self: Pin<&mut Self>, ctx: &mut Context<'_>) -> Poll<Self::Output> {
self.sigterm.poll_recv(ctx)
}
}
/// Start the server waiting for incoming connections or a CTRL+C signal /// Start the server waiting for incoming connections or a CTRL+C signal
pub async fn run( pub async fn run(
ports: PortConfig, ports: PortConfig,
@ -294,12 +322,28 @@ pub async fn run(
MultiListener::new_multi(secure_listener, insecure_listener, ssl).await? MultiListener::new_multi(secure_listener, insecure_listener, ssl).await?
} }
}; };
#[cfg(not(unix))]
{
// Non-unix, usually Windows specific signal handling.
// FIXME(@ohsayan): For now, let's just
// bother with ctrl+c, we'll move ahead as users require them
tokio::select! { tokio::select! {
_ = server.run_server() => {} _ = server.run_server() => {}
_ = sig => { _ = sig => {}
log::info!("Signalling all workers to shut down");
} }
} }
#[cfg(unix)]
{
let sigterm = UnixTerminationSignal::init()?;
// apart from CTRLC, the only other thing we care about is SIGTERM
// FIXME(@ohsayan): Maybe we should respond to SIGHUP too?
tokio::select! {
_ = server.run_server() => {},
_ = sig => {},
_ = sigterm => {}
}
}
log::info!("Signalling all workers to shut down");
// drop the signal and let others exit // drop the signal and let others exit
drop(signal); drop(signal);
server.finish_with_termsig().await; server.finish_with_termsig().await;

@ -108,7 +108,7 @@ fn main() {
// uh oh, something happened while starting up // uh oh, something happened while starting up
log::error!("{}", e); log::error!("{}", e);
pre_shutdown_cleanup(pid_file); pre_shutdown_cleanup(pid_file);
process::exit(0x100); process::exit(1);
} }
}; };
assert_eq!( assert_eq!(
@ -141,7 +141,7 @@ pub fn pre_shutdown_cleanup(pid_file: fs::File) {
drop(pid_file); drop(pid_file);
if let Err(e) = fs::remove_file(PATH) { if let Err(e) = fs::remove_file(PATH) {
log::error!("Shutdown failure: Failed to remove pid file: {}", e); log::error!("Shutdown failure: Failed to remove pid file: {}", e);
process::exit(0x100); process::exit(0x01);
} }
} }
@ -168,7 +168,7 @@ fn check_args_and_get_cfg() -> (PortConfig, BGSave, SnapshotConfig, Option<Strin
} }
Err(e) => { Err(e) => {
log::error!("{}", e); log::error!("{}", e);
std::process::exit(0x100); std::process::exit(0x01);
} }
}; };
binding_and_cfg binding_and_cfg
@ -190,7 +190,7 @@ fn run_pre_startup_tasks() -> fs::File {
"Startup failure: Another process with parent PID {} is using the data directory", "Startup failure: Another process with parent PID {} is using the data directory",
pid pid
); );
process::exit(0x100); process::exit(0x01);
} }
let mut file = match fs::OpenOptions::new() let mut file = match fs::OpenOptions::new()
.create(true) .create(true)
@ -201,12 +201,12 @@ fn run_pre_startup_tasks() -> fs::File {
Ok(fle) => fle, Ok(fle) => fle,
Err(e) => { Err(e) => {
log::error!("Startup failure: Failed to open pid file: {}", e); log::error!("Startup failure: Failed to open pid file: {}", e);
process::exit(0x100); process::exit(0x01);
} }
}; };
if let Err(e) = file.write_all(process::id().to_string().as_bytes()) { if let Err(e) = file.write_all(process::id().to_string().as_bytes()) {
log::error!("Startup failure: Failed to write to pid file: {}", e); log::error!("Startup failure: Failed to write to pid file: {}", e);
process::exit(0x100); process::exit(0x01);
} }
file file
} }

@ -60,7 +60,7 @@ macro_rules! sanity_test {
macro_rules! err { macro_rules! err {
($note:expr) => {{ ($note:expr) => {{
eprintln!("ERROR: {}", $note); eprintln!("ERROR: {}", $note);
std::process::exit(0x100); std::process::exit(0x01);
}}; }};
} }

Loading…
Cancel
Save