From 5d551c1cc10669e6c860c6d8fa33ce07fd368198 Mon Sep 17 00:00:00 2001 From: austinabell Date: Thu, 20 Feb 2020 10:06:28 -0500 Subject: [PATCH 1/6] Run networking service in seperate thread and handle SIGINT --- forest/Cargo.toml | 1 + forest/src/main.rs | 27 +++++++++++++++++++++++++-- 2 files changed, 26 insertions(+), 2 deletions(-) diff --git a/forest/Cargo.toml b/forest/Cargo.toml index ed32b7b9cc4d..160c6f5e034a 100644 --- a/forest/Cargo.toml +++ b/forest/Cargo.toml @@ -17,3 +17,4 @@ slog-async = "2.3.0" slog-term = "2.4.2" async-std = { version = "1.4.0", features = ["attributes"] } serde = { version = "1.0", features = ["derive"] } +ctrlc = "3.1.4" diff --git a/forest/src/main.rs b/forest/src/main.rs index d37b6730fb60..5f5ed04c5e1f 100644 --- a/forest/src/main.rs +++ b/forest/src/main.rs @@ -10,6 +10,9 @@ use forest_libp2p::{get_keypair, Libp2pService}; use libp2p::identity::{ed25519, Keypair}; use slog::{info, trace}; use utils::write_to_file; +use std::process; +use std::sync::atomic::{AtomicUsize, Ordering}; +use std::sync::Arc; #[async_std::main] async fn main() { @@ -36,11 +39,31 @@ async fn main() { } }; - let lp2p_service = Libp2pService::new(logger, &config.network, net_keypair); + let running = Arc::new(AtomicUsize::new(0)); + let r = running.clone(); + ctrlc::set_handler(move || { + let prev = r.fetch_add(1, Ordering::SeqCst); + if prev == 0 { + println!("Got interrupt, shutting down..."); + } else { + process::exit(0); + } + }).expect("Error setting Ctrl-C handler"); - task::block_on(async move { + // Start libp2p service + let lp2p_service = Libp2pService::new(logger, &config.network, net_keypair); + let lp2p_thread = task::spawn(async { lp2p_service.run().await; }); + loop { + if running.load(Ordering::SeqCst) > 0 { + // TODO change dropping threads to gracefully shutting down services + // or implement drop on components with sensitive shutdown + drop(lp2p_thread); + break; + } + } + info!(log, "Forest finish shutdown"); } From 5403a06a7ef9d6c0110278b5fa511af7530d2dab Mon Sep 17 00:00:00 2001 From: austinabell Date: Thu, 20 Feb 2020 10:13:39 -0500 Subject: [PATCH 2/6] fmt --- forest/src/main.rs | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/forest/src/main.rs b/forest/src/main.rs index 5f5ed04c5e1f..0e7ad289e745 100644 --- a/forest/src/main.rs +++ b/forest/src/main.rs @@ -9,10 +9,10 @@ use async_std::task; use forest_libp2p::{get_keypair, Libp2pService}; use libp2p::identity::{ed25519, Keypair}; use slog::{info, trace}; -use utils::write_to_file; use std::process; use std::sync::atomic::{AtomicUsize, Ordering}; use std::sync::Arc; +use utils::write_to_file; #[async_std::main] async fn main() { @@ -48,7 +48,8 @@ async fn main() { } else { process::exit(0); } - }).expect("Error setting Ctrl-C handler"); + }) + .expect("Error setting Ctrl-C handler"); // Start libp2p service let lp2p_service = Libp2pService::new(logger, &config.network, net_keypair); From 8654883f2a41ecdc5dbe6c5d410af9242824fc88 Mon Sep 17 00:00:00 2001 From: austinabell Date: Thu, 20 Feb 2020 10:20:55 -0500 Subject: [PATCH 3/6] change variable name --- forest/src/main.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/forest/src/main.rs b/forest/src/main.rs index 0e7ad289e745..5070b2f7cc82 100644 --- a/forest/src/main.rs +++ b/forest/src/main.rs @@ -52,9 +52,9 @@ async fn main() { .expect("Error setting Ctrl-C handler"); // Start libp2p service - let lp2p_service = Libp2pService::new(logger, &config.network, net_keypair); + let p2p_service = Libp2pService::new(logger, &config.network, net_keypair); let lp2p_thread = task::spawn(async { - lp2p_service.run().await; + p2p_service.run().await; }); loop { From 8fe6afc0b0657728b298d5a62df122727dc3382b Mon Sep 17 00:00:00 2001 From: austinabell Date: Thu, 20 Feb 2020 11:33:43 -0500 Subject: [PATCH 4/6] Greg is literally trolling --- forest/src/main.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/forest/src/main.rs b/forest/src/main.rs index 5070b2f7cc82..d0f07d3bc8b4 100644 --- a/forest/src/main.rs +++ b/forest/src/main.rs @@ -53,7 +53,7 @@ async fn main() { // Start libp2p service let p2p_service = Libp2pService::new(logger, &config.network, net_keypair); - let lp2p_thread = task::spawn(async { + let p2p_thread = task::spawn(async { p2p_service.run().await; }); @@ -61,7 +61,7 @@ async fn main() { if running.load(Ordering::SeqCst) > 0 { // TODO change dropping threads to gracefully shutting down services // or implement drop on components with sensitive shutdown - drop(lp2p_thread); + drop(p2p_thread); break; } } From 7a0e348edaf88c3c030a084678a3d889b9d5b491 Mon Sep 17 00:00:00 2001 From: austinabell Date: Thu, 20 Feb 2020 12:40:40 -0500 Subject: [PATCH 5/6] Add thread sleep to avoid busy loop --- forest/src/main.rs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/forest/src/main.rs b/forest/src/main.rs index d0f07d3bc8b4..ada386d88d3c 100644 --- a/forest/src/main.rs +++ b/forest/src/main.rs @@ -12,6 +12,8 @@ use slog::{info, trace}; use std::process; use std::sync::atomic::{AtomicUsize, Ordering}; use std::sync::Arc; +use std::thread; +use std::time::Duration; use utils::write_to_file; #[async_std::main] @@ -58,6 +60,7 @@ async fn main() { }); loop { + thread::sleep(Duration::from_secs(2)); if running.load(Ordering::SeqCst) > 0 { // TODO change dropping threads to gracefully shutting down services // or implement drop on components with sensitive shutdown From 1b3f3d25b7db3859095c454ea6d907bb47d1cb2b Mon Sep 17 00:00:00 2001 From: austinabell Date: Thu, 20 Feb 2020 13:47:17 -0500 Subject: [PATCH 6/6] change from sleeping thread to oneshot channel --- forest/src/main.rs | 52 ++++++++++++++++++++++++++-------------------- 1 file changed, 29 insertions(+), 23 deletions(-) diff --git a/forest/src/main.rs b/forest/src/main.rs index ada386d88d3c..1d0db53acc27 100644 --- a/forest/src/main.rs +++ b/forest/src/main.rs @@ -9,13 +9,35 @@ use async_std::task; use forest_libp2p::{get_keypair, Libp2pService}; use libp2p::identity::{ed25519, Keypair}; use slog::{info, trace}; +use std::cell::RefCell; use std::process; use std::sync::atomic::{AtomicUsize, Ordering}; use std::sync::Arc; -use std::thread; -use std::time::Duration; use utils::write_to_file; +// Blocks current thread until ctrl-c is received +fn block_until_sigint() { + let (ctrlc_send, ctrlc_oneshot) = futures::channel::oneshot::channel(); + let ctrlc_send_c = RefCell::new(Some(ctrlc_send)); + + let running = Arc::new(AtomicUsize::new(0)); + ctrlc::set_handler(move || { + let prev = running.fetch_add(1, Ordering::SeqCst); + if prev == 0 { + println!("Got interrupt, shutting down..."); + // Send sig int in channel to blocking task + if let Some(ctrlc_send) = ctrlc_send_c.try_borrow_mut().unwrap().take() { + ctrlc_send.send(()).expect("Error sending ctrl-c message"); + } + } else { + process::exit(0); + } + }) + .expect("Error setting Ctrl-C handler"); + + task::block_on(ctrlc_oneshot).unwrap(); +} + #[async_std::main] async fn main() { let log = log::setup_logging(); @@ -41,33 +63,17 @@ async fn main() { } }; - let running = Arc::new(AtomicUsize::new(0)); - let r = running.clone(); - ctrlc::set_handler(move || { - let prev = r.fetch_add(1, Ordering::SeqCst); - if prev == 0 { - println!("Got interrupt, shutting down..."); - } else { - process::exit(0); - } - }) - .expect("Error setting Ctrl-C handler"); - // Start libp2p service let p2p_service = Libp2pService::new(logger, &config.network, net_keypair); let p2p_thread = task::spawn(async { p2p_service.run().await; }); - loop { - thread::sleep(Duration::from_secs(2)); - if running.load(Ordering::SeqCst) > 0 { - // TODO change dropping threads to gracefully shutting down services - // or implement drop on components with sensitive shutdown - drop(p2p_thread); - break; - } - } + // Block until ctrl-c is hit + block_until_sigint(); + + // Drop threads + drop(p2p_thread); info!(log, "Forest finish shutdown"); }