diff --git a/src/rustylee/build_number.txt b/src/rustylee/build_number.txt index af21323..50f0bcd 100644 --- a/src/rustylee/build_number.txt +++ b/src/rustylee/build_number.txt @@ -1 +1 @@ -133 \ No newline at end of file +135 \ No newline at end of file diff --git a/src/rustylee/src/main.rs b/src/rustylee/src/main.rs index 4e799a8..f81eb06 100644 --- a/src/rustylee/src/main.rs +++ b/src/rustylee/src/main.rs @@ -5,6 +5,7 @@ use tracing::info; use std::sync::atomic::{AtomicBool, Ordering}; use std::sync::Arc; use std::sync::mpsc; +use std::sync::mpsc::{Receiver, Sender}; use std::thread; use std::time::{Duration, Instant}; @@ -12,57 +13,68 @@ use crate::brain::Brain; use crate::lifecycle::{LifeState, LifecycleCommand}; fn main() { - let _semantic_version = env!("CARGO_PKG_VERSION").to_string(); let shutdown_requested = Arc::new(AtomicBool::new(false)); - let s = shutdown_requested.clone(); setup_logging(); info!("RustyLee: {}", env!("FULL_VERSION")); - ctrlc::set_handler(move || { - info!("[Signal] Shutdown signal caught!"); - s.store(true, Ordering::SeqCst); - }).expect("Error setting signal handler"); + setup_os_signal_handler(shutdown_requested.clone()); + let (tx, rx) = spawn_brain(); + let_there_be_life(&tx, &rx); + wait_for_death(tx, rx); - // 1. Setup the Divine Nerves - let (to_brain_tx, to_brain_rx) = mpsc::channel::(); - let (from_brain_tx, from_brain_rx) = mpsc::channel::(); + info!("God: Brain has been buried. Shutting down."); +} - // 2. Spawn the Brain thread - thread::spawn(move || { - let mut brain = Brain::new(to_brain_rx, from_brain_tx); - brain.run(); +fn wait_for_death(tx: Sender, rx: Receiver) { + info!("God: Resting for 10 seconds..."); + thread::sleep(Duration::from_secs(10)); + + info!("God: Commanding Burial..."); + let _ = tx.send(LifecycleCommand { + required_state: LifeState::Buried, + command_time: Instant::now(), }); + if let Ok(reply) = rx.recv() { + info!("Brain: {}", reply); + } +} + +fn let_there_be_life(tx: &Sender, rx: &Receiver) { // 3. Command: Genisys info!("God: Commanding Genisys..."); - let _ = to_brain_tx.send(LifecycleCommand { + let _ = tx.send(LifecycleCommand { required_state: LifeState::Genisys, command_time: Instant::now(), }); // Wait for Brain's "OK" - if let Ok(reply) = from_brain_rx.recv() { + if let Ok(reply) = rx.recv() { info!("Brain: {}", reply); } +} - // 4. Wait two seconds - info!("God: Resting for 2 seconds..."); - thread::sleep(Duration::from_secs(2)); +fn spawn_brain() -> (Sender, Receiver) { + let (to_brain_tx, to_brain_rx) = mpsc::channel::(); + let (from_brain_tx, from_brain_rx) = mpsc::channel::(); - // 5. Command: Buried - info!("God: Commanding Burial..."); - let _ = to_brain_tx.send(LifecycleCommand { - required_state: LifeState::Buried, - command_time: Instant::now(), + // The Brain takes one half of each pair + thread::spawn(move || { + let mut brain = Brain::new(to_brain_rx, from_brain_tx); + brain.run(); }); - // Wait for Brain's final "OK" - if let Ok(reply) = from_brain_rx.recv() { - info!("Brain: {}", reply); - } + // Main gets the remaining halves (the "Remote Control") + (to_brain_tx, from_brain_rx) +} - info!("God: Brain has been buried. Shutting down."); +fn setup_os_signal_handler(s: Arc) { + info!("Setting up SIGTERM/SIGINT handling."); + ctrlc::set_handler(move || { + info!("[Signal] Shutdown signal caught!"); + s.store(true, Ordering::SeqCst); + }).expect("Error setting signal handler."); } fn setup_logging() {