Merge pull request #111 from uqbar-dao/hf/intercept-sigs

gracefully exit in case of many SIG*s
This commit is contained in:
hosted-fornet 2023-12-26 09:20:56 -08:00 committed by GitHub
commit 41e01b1a72
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 37 additions and 5 deletions

1
Cargo.lock generated
View File

@ -4698,6 +4698,7 @@ dependencies = [
"mio", "mio",
"num_cpus", "num_cpus",
"pin-project-lite", "pin-project-lite",
"signal-hook-registry",
"socket2 0.5.4", "socket2 0.5.4",
"tokio-macros", "tokio-macros",
"windows-sys 0.48.0", "windows-sys 0.48.0",

View File

@ -55,7 +55,9 @@ rand = "0.8.4"
reqwest = "0.11.18" reqwest = "0.11.18"
ring = "0.16.20" ring = "0.16.20"
rmp-serde = "1.1.2" rmp-serde = "1.1.2"
rocksdb = { version = "0.21.0", features = ["multi-threaded-cf"] }
route-recognizer = "0.3.1" route-recognizer = "0.3.1"
rusqlite = { version = "0.30.0", features = ["bundled"] }
serde = { version = "1.0", features = ["derive"] } serde = { version = "1.0", features = ["derive"] }
serde_json = "1.0" serde_json = "1.0"
serde_urlencoded = "0.7" serde_urlencoded = "0.7"
@ -63,7 +65,7 @@ sha2 = "0.10"
snow = { version = "0.9.3", features = ["ring-resolver"] } snow = { version = "0.9.3", features = ["ring-resolver"] }
static_dir = "0.2.0" static_dir = "0.2.0"
thiserror = "1.0" thiserror = "1.0"
tokio = { version = "1.28", features = ["fs", "macros", "rt-multi-thread", "sync"] } tokio = { version = "1.28", features = ["fs", "macros", "rt-multi-thread", "signal", "sync"] }
tokio-tungstenite = "0.20.1" tokio-tungstenite = "0.20.1"
url = "2.4.1" url = "2.4.1"
uuid = { version = "1.1.2", features = ["serde", "v4"] } uuid = { version = "1.1.2", features = ["serde", "v4"] }
@ -71,5 +73,3 @@ warp = "0.3.5"
wasmtime = "15.0.1" wasmtime = "15.0.1"
wasmtime-wasi = "15.0.1" wasmtime-wasi = "15.0.1"
zip = "0.6" zip = "0.6"
rocksdb = { version = "0.21.0", features = ["multi-threaded-cf"] }
rusqlite = { version = "0.30.0", features = ["bundled"] }

View File

@ -472,6 +472,7 @@ async fn main() {
)); ));
// if a runtime task exits, try to recover it, // if a runtime task exits, try to recover it,
// unless it was terminal signaling a quit // unless it was terminal signaling a quit
// or a SIG* was intercepted
let quit_msg: String = tokio::select! { let quit_msg: String = tokio::select! {
Some(Ok(res)) = tasks.join_next() => { Some(Ok(res)) = tasks.join_next() => {
format!( format!(
@ -521,6 +522,13 @@ async fn main() {
// abort all remaining tasks // abort all remaining tasks
tasks.shutdown().await; tasks.shutdown().await;
let stdout = std::io::stdout();
let mut stdout = stdout.lock();
let _ = crossterm::execute!(
stdout,
crossterm::event::DisableBracketedPaste,
crossterm::terminal::SetTitle(""),
);
let _ = crossterm::terminal::disable_raw_mode(); let _ = crossterm::terminal::disable_raw_mode();
println!("\r\n\x1b[38;5;196m{}\x1b[0m", quit_msg); println!("\r\n\x1b[38;5;196m{}\x1b[0m", quit_msg);
return; return;

View File

@ -14,6 +14,7 @@ use crossterm::{
use futures::{future::FutureExt, StreamExt}; use futures::{future::FutureExt, StreamExt};
use std::fs::{read_to_string, OpenOptions}; use std::fs::{read_to_string, OpenOptions};
use std::io::{stdout, BufWriter, Write}; use std::io::{stdout, BufWriter, Write};
use tokio::signal::unix::{signal, SignalKind};
mod utils; mod utils;
@ -129,6 +130,20 @@ pub async fn terminal(
.unwrap(); .unwrap();
let mut log_writer = BufWriter::new(log_handle); let mut log_writer = BufWriter::new(log_handle);
// use to trigger cleanup if receive signal to kill process
let mut sigalrm = signal(SignalKind::alarm()).expect("uqbar: failed to set up SIGALRM handler");
let mut sighup = signal(SignalKind::hangup()).expect("uqbar: failed to set up SIGHUP handler");
let mut sigint =
signal(SignalKind::interrupt()).expect("uqbar: failed to set up SIGINT handler");
let mut sigpipe = signal(SignalKind::pipe()).expect("uqbar: failed to set up SIGPIPE handler");
let mut sigquit = signal(SignalKind::quit()).expect("uqbar: failed to set up SIGQUIT handler");
let mut sigterm =
signal(SignalKind::terminate()).expect("uqbar: failed to set up SIGTERM handler");
let mut sigusr1 =
signal(SignalKind::user_defined1()).expect("uqbar: failed to set up SIGUSR1 handler");
let mut sigusr2 =
signal(SignalKind::user_defined2()).expect("uqbar: failed to set up SIGUSR2 handler");
loop { loop {
let event = reader.next().fuse(); let event = reader.next().fuse();
@ -172,7 +187,7 @@ pub async fn terminal(
Print(utils::truncate_in_place(&current_line, prompt_len, win_cols, (line_col, cursor_col))), Print(utils::truncate_in_place(&current_line, prompt_len, win_cols, (line_col, cursor_col))),
cursor::MoveTo(cursor_col, win_rows), cursor::MoveTo(cursor_col, win_rows),
)?; )?;
}, }
Some(Ok(event)) = event => { Some(Ok(event)) = event => {
let mut stdout = stdout.lock(); let mut stdout = stdout.lock();
match event { match event {
@ -599,7 +614,15 @@ pub async fn terminal(
}, },
_ => {}, _ => {},
} }
} }
_ = sigalrm.recv() => return Err(anyhow::anyhow!("exiting due to SIGALRM")),
_ = sighup.recv() => return Err(anyhow::anyhow!("exiting due to SIGHUP")),
_ = sigint.recv() => return Err(anyhow::anyhow!("exiting due to SIGINT")),
_ = sigpipe.recv() => return Err(anyhow::anyhow!("exiting due to SIGPIPE")),
_ = sigquit.recv() => return Err(anyhow::anyhow!("exiting due to SIGQUIT")),
_ = sigterm.recv() => return Err(anyhow::anyhow!("exiting due to SIGTERM")),
_ = sigusr1.recv() => return Err(anyhow::anyhow!("exiting due to SIGUSR1")),
_ = sigusr2.recv() => return Err(anyhow::anyhow!("exiting due to SIGUSR2")),
} }
} }
execute!(stdout.lock(), DisableBracketedPaste, terminal::SetTitle(""))?; execute!(stdout.lock(), DisableBracketedPaste, terminal::SetTitle(""))?;