From bbe6ed8bc2b39da45394ab0203e6dc13739a5eb5 Mon Sep 17 00:00:00 2001 From: Jose Quintana Date: Thu, 7 Jan 2021 01:34:01 +0100 Subject: [PATCH] feat: termination signals support --- src/bin/server.rs | 13 +++++++++---- src/core/mod.rs | 4 ++-- src/core/signal_manager.rs | 56 -------------------------------------------------------- src/core/signals.rs | 51 +++++++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 62 insertions(+), 62 deletions(-) delete mode 100644 src/core/signal_manager.rs create mode 100644 src/core/signals.rs diff --git a/src/bin/server.rs b/src/bin/server.rs index 4f17f92..6254d82 100644 --- a/src/bin/server.rs +++ b/src/bin/server.rs @@ -7,7 +7,7 @@ static ALLOC: jemallocator::Jemalloc = jemallocator::Jemalloc; extern crate static_web_server; use structopt::StructOpt; -use tracing::info; +use tracing::warn; use warp::Filter; use self::static_web_server::core::*; @@ -22,11 +22,16 @@ async fn server(opts: config::Options) -> Result { .recover(rejection::handle_rejection) .with(warp::trace::request()); - info!("listening on http://[{}]:{}", &opts.host, &opts.port); - let host = opts.host.parse::()?; + let port = opts.port; + + tokio::task::spawn(warp::serve(filters).run((host, port))); - warp::serve(filters).run((host, opts.port)).await; + signals::wait(|sig: signals::Signal| { + let code = signals::as_int(sig); + warn!("Signal {} caught. Server execution exited.", code); + std::process::exit(code) + }); Ok(()) } diff --git a/src/core/mod.rs b/src/core/mod.rs index e68fe1d..161938e 100644 --- a/src/core/mod.rs +++ b/src/core/mod.rs @@ -2,9 +2,9 @@ pub mod config; pub mod helpers; pub mod logger; pub mod rejection; -pub mod signal_manager; +pub mod signals; #[macro_use] pub mod result; -pub use crate::core::result::*; +pub use result::*; diff --git a/src/core/signal_manager.rs b/src/core/signal_manager.rs deleted file mode 100644 index 06be40c..0000000 --- a/src/core/signal_manager.rs +++ /dev/null @@ -1,56 +0,0 @@ -use nix::errno::Errno; -use nix::libc::c_int; -use nix::sys::signal::{SIGCHLD, SIGINT, SIGTERM}; -use nix::sys::wait::WaitStatus::{Exited, Signaled, StillAlive}; -use nix::sys::wait::{waitpid, WaitPidFlag}; -use nix::Error; -use signal::trap::Trap; - -/// It waits for an incoming Termination Signal like Ctrl+C (SIGINT), SIGTERM, etc -pub fn wait_for_signal(f: F) -where - F: Fn(signal::Signal), -{ - let signal_trap = Trap::trap(&[SIGTERM, SIGINT, SIGCHLD]); - - for sig in signal_trap { - match sig { - SIGCHLD => { - // Current std::process::Command ip does not have a way to find - // process id, so we just wait until we have no children - loop { - match waitpid(None, Some(WaitPidFlag::WNOHANG)) { - Ok(Exited(pid, status)) => { - println!("{} exited with status {}", pid, status); - continue; - } - Ok(Signaled(pid, sig, _)) => { - println!("{} killed by {}", pid, sig as c_int); - continue; - } - Ok(StillAlive) => { - break; - } - Ok(status) => { - println!("Temporary status {:?}", status); - continue; - } - Err(Error::Sys(Errno::ECHILD)) => { - return; - } - Err(e) => { - panic!("Error {:?}", e); - } - } - } - } - - sig => f(sig), - } - } -} - -/// It casts a `signal::Signal` to `i32` -pub fn signal_to_int(sig: signal::Signal) -> i32 { - sig as c_int -} diff --git a/src/core/signals.rs b/src/core/signals.rs new file mode 100644 index 0000000..6947b11 --- /dev/null +++ b/src/core/signals.rs @@ -0,0 +1,51 @@ +use nix::errno::Errno; +use nix::libc::c_int; +use nix::sys::signal::{SIGCHLD, SIGINT, SIGTERM}; +use nix::sys::wait::WaitStatus::{Exited, Signaled, StillAlive}; +use nix::sys::wait::{waitpid, WaitPidFlag}; +use nix::Error; + +pub use signal::Signal; + +/// It waits for an incoming Termination Signal like Ctrl+C (SIGINT), SIGTERM, etc +pub fn wait(func: F) +where + F: Fn(signal::Signal), +{ + let sig_trap = signal::trap::Trap::trap(&[SIGTERM, SIGINT, SIGCHLD]); + for sig in sig_trap { + match sig { + SIGCHLD => { + // Current std::process::Command ip does not have a way to find + // process id, so we just wait until we have no children + loop { + match waitpid(None, Some(WaitPidFlag::WNOHANG)) { + Ok(Exited(pid, status)) => { + println!("{} exited with status {}", pid, status); + continue; + } + Ok(Signaled(pid, sig, _)) => { + println!("{} killed by {}", pid, sig as c_int); + continue; + } + Ok(StillAlive) => break, + Ok(status) => { + println!("Temporary status {:?}", status); + continue; + } + Err(Error::Sys(Errno::ECHILD)) => return, + Err(e) => { + panic!("Error {:?}", e); + } + } + } + } + sig => func(sig), + } + } +} + +/// It casts a given `signal::Signal` to `i32`. +pub fn as_int(sig: signal::Signal) -> i32 { + sig as c_int +} -- libgit2 1.7.2