From 1d8cd8830910cfd0b2e59b89b5850fa75fa75b91 Mon Sep 17 00:00:00 2001 From: hinto-janaiyo Date: Wed, 30 Nov 2022 21:58:32 -0500 Subject: [PATCH] helper: create wireframe of the [Helper::helper()] event loop --- src/constants.rs | 1 + src/helper.rs | 111 ++++++++++++++++++++++++++++++++++++----------- 2 files changed, 87 insertions(+), 25 deletions(-) diff --git a/src/constants.rs b/src/constants.rs index 3b41597..85ea736 100644 --- a/src/constants.rs +++ b/src/constants.rs @@ -54,6 +54,7 @@ pub const BLACK: egui::Color32 = egui::Color32::BLACK; // [Duration] constants pub const SECOND: std::time::Duration = std::time::Duration::from_secs(1); +pub const TOKIO_SECOND: tokio::time::Duration = std::time::Duration::from_secs(1); // OS specific #[cfg(target_os = "windows")] diff --git a/src/helper.rs b/src/helper.rs index 2d4ccbf..fe01f77 100644 --- a/src/helper.rs +++ b/src/helper.rs @@ -48,24 +48,15 @@ use log::*; //---------------------------------------------------------------------------------------------------- [Helper] Struct // A meta struct holding all the data that gets processed in this thread pub struct Helper { - uptime: HumanTime, // Gupax uptime formatting for humans + instant: Instant, // Gupax start as an [Instant] + human_time: HumanTime, // Gupax uptime formatting for humans p2pool: Process, // P2Pool process state xmrig: Process, // XMRig process state p2pool_api: P2poolApi, // P2Pool API state xmrig_api: XmrigApi, // XMRig API state } -impl Helper { - pub fn new(instant: std::time::Instant) -> Self { - Self { - uptime: HumanTime::into_human(instant.elapsed()), - p2pool: Process::new(ProcessName::P2pool, String::new(), PathBuf::new()), - xmrig: Process::new(ProcessName::Xmrig, String::new(), PathBuf::new()), - p2pool_api: P2poolApi::new(), - xmrig_api: XmrigApi::new(), - } - } -} +// Impl found at the very bottom of this file. //---------------------------------------------------------------------------------------------------- [Process] Struct // This holds all the state of a (child) process. @@ -224,17 +215,87 @@ impl XmrigApi { } } -//---------------------------------------------------------------------------------------------------- The "helper" loop -#[tokio::main] -pub async fn helper() { - thread::spawn(|| { loop { - // 1. Spawn child processes (if signal found) - // 2. Create stdout pipe thread (if new child process) - // 3. Send stdin (if signal found) - // 4. Kill child process (if signal found) - // 4. Collect P2Pool API task (if alive) - // 5. Collect XMRig HTTP API task (if alive) - // 6. Execute all async tasks - // 7. Set Gupax/P2Pool/XMRig uptime - }}); +//---------------------------------------------------------------------------------------------------- [Helper] +impl Helper { + pub fn new(instant: std::time::Instant) -> Self { + Self { + instant, + human_time: HumanTime::into_human(instant.elapsed()), + p2pool: Process::new(ProcessName::P2pool, String::new(), PathBuf::new()), + xmrig: Process::new(ProcessName::Xmrig, String::new(), PathBuf::new()), + p2pool_api: P2poolApi::new(), + xmrig_api: XmrigApi::new(), + } + } + + // Intermediate function that spawns the helper thread. + pub fn spawn_helper(helper: &Arc>) { + let helper = Arc::clone(helper); + thread::spawn(move || { Self::helper(helper); }); + } + + // The "helper" loop + // [helper] = Actual Arc + // [h] = Temporary lock that gets dropped + // [jobs] = Vector of async jobs ready to go + #[tokio::main] + pub async fn helper(helper: Arc>) { + // Begin loop + loop { + + // 1. Create "jobs" vector holding async tasks + let jobs: Vec>> = vec![]; + + // 2. Loop init timestamp + let start = Instant::now(); + + // 3. Spawn child processes (if signal found) + let h = helper.lock().unwrap(); + if let ProcessSignal::Start = h.p2pool.signal { + // Start outer thread, start inner stdout/stderr pipe, loop in outer thread for stdin/signal/etc + if !h.p2pool.input.is_empty() { + // Process STDIN + } + } + drop(h); + let h = helper.lock().unwrap(); + if let ProcessSignal::Start = h.xmrig.signal { + // Start outer thread, start inner stdout/stderr pipe, loop in outer thread for stdin/signal/etc + if !h.xmrig.input.is_empty() { + // Process STDIN + } + } + drop(h); + + // 4. Collect P2Pool API task (if alive) + let h = helper.lock().unwrap(); + if let ProcessState::Alive = h.p2pool.state { + } + // 5. Collect XMRig HTTP API task (if alive) + if let ProcessState::Alive = h.xmrig.state { + } + drop(h); + + // 6. Execute all async tasks + for job in jobs { + job.await; + } + + // 7. Set Gupax/P2Pool/XMRig uptime + let mut h = helper.lock().unwrap(); + h.human_time = HumanTime::into_human(h.instant.elapsed()); + drop(h); + + // 8. Calculate if we should sleep or not. + // If we should sleep, how long? + let elapsed = start.elapsed().as_millis(); + if elapsed < 1000 { + // Casting from u128 to u64 should be safe here, because [elapsed] + // is less than 1000, meaning it can fit into a u64 easy. + std::thread::sleep(std::time::Duration::from_millis((1000-elapsed) as u64)); + } + + // 9. End loop + } + } }