mirror of
https://github.com/hinto-janai/gupax.git
synced 2025-03-12 09:31:38 +00:00
helper: add initial struct, add [HumanTime] for formatting uptime
This commit is contained in:
parent
eb4a70c483
commit
c6dad5849d
2 changed files with 138 additions and 24 deletions
130
src/helper.rs
130
src/helper.rs
|
@ -39,11 +39,34 @@ use std::{
|
|||
sync::{Arc,Mutex},
|
||||
path::PathBuf,
|
||||
process::Command,
|
||||
time::*,
|
||||
thread,
|
||||
};
|
||||
use crate::constants::*;
|
||||
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
|
||||
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(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------- [Process] Struct
|
||||
// This holds all the state of a (child) process.
|
||||
// The main GUI thread will use this to display console text, online state, etc.
|
||||
|
@ -51,6 +74,8 @@ pub struct Process {
|
|||
name: ProcessName, // P2Pool or XMRig?
|
||||
state: ProcessState, // The state of the process (alive, dead, etc)
|
||||
signal: ProcessSignal, // Did the user click [Start/Stop/Restart]?
|
||||
start: Instant, // Starttime of process
|
||||
uptime: HumanTime, // Uptime of process
|
||||
output: String, // This is the process's stdout + stderr
|
||||
// STDIN Problem:
|
||||
// - User can input many many commands in 1 second
|
||||
|
@ -68,10 +93,13 @@ pub struct Process {
|
|||
//---------------------------------------------------------------------------------------------------- [Process] Impl
|
||||
impl Process {
|
||||
pub fn new(name: ProcessName, args: String, path: PathBuf) -> Self {
|
||||
let now = Instant::now();
|
||||
Self {
|
||||
name,
|
||||
state: ProcessState::Dead,
|
||||
signal: ProcessSignal::None,
|
||||
start: now,
|
||||
uptime: HumanTime::into_human(now.elapsed()),
|
||||
// P2Pool log level 1 produces a bit less than 100,000 lines a day.
|
||||
// Assuming each line averages 80 UTF-8 scalars (80 bytes), then this
|
||||
// initial buffer should last around a week (56MB) before resetting.
|
||||
|
@ -108,27 +136,105 @@ pub enum ProcessSignal {
|
|||
|
||||
#[derive(Copy,Clone,Eq,PartialEq,Debug)]
|
||||
pub enum ProcessName {
|
||||
P2Pool,
|
||||
XMRig,
|
||||
P2pool,
|
||||
Xmrig,
|
||||
}
|
||||
|
||||
impl std::fmt::Display for ProcessState { fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { write!(f, "{:#?}", self) } }
|
||||
impl std::fmt::Display for ProcessSignal { fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { write!(f, "{:#?}", self) } }
|
||||
impl std::fmt::Display for ProcessName { fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { write!(f, "{:#?}", self) } }
|
||||
|
||||
//---------------------------------------------------------------------------------------------------- [HumanTime]
|
||||
// This converts a [std::time::Duration] into something more readable.
|
||||
// Used for uptime display purposes: [7 years, 8 months, 15 days, 23 hours, 35 minutes, 1 second]
|
||||
// Code taken from [https://docs.rs/humantime/] and edited to remove sub-second time, change spacing and some words.
|
||||
use std::time::Duration;
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct HumanTime(Duration);
|
||||
|
||||
impl HumanTime {
|
||||
pub fn into_human(d: Duration) -> HumanTime {
|
||||
HumanTime(d)
|
||||
}
|
||||
|
||||
fn plural(f: &mut std::fmt::Formatter, started: &mut bool, name: &str, value: u64) -> std::fmt::Result {
|
||||
if value > 0 {
|
||||
if *started { f.write_str(" ")?; }
|
||||
}
|
||||
write!(f, "{}{}", value, name)?;
|
||||
if value > 1 {
|
||||
f.write_str("s")?;
|
||||
}
|
||||
*started = true;
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
impl std::fmt::Display for HumanTime {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
|
||||
let secs = self.0.as_secs();
|
||||
if secs == 0 {
|
||||
f.write_str("0s")?;
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
let years = secs / 31_557_600; // 365.25d
|
||||
let ydays = secs % 31_557_600;
|
||||
let months = ydays / 2_630_016; // 30.44d
|
||||
let mdays = ydays % 2_630_016;
|
||||
let days = mdays / 86400;
|
||||
let day_secs = mdays % 86400;
|
||||
let hours = day_secs / 3600;
|
||||
let minutes = day_secs % 3600 / 60;
|
||||
let seconds = day_secs % 60;
|
||||
|
||||
let ref mut started = false;
|
||||
Self::plural(f, started, " year", years)?;
|
||||
Self::plural(f, started, " month", months)?;
|
||||
Self::plural(f, started, " day", days)?;
|
||||
Self::plural(f, started, " hour", hours)?;
|
||||
Self::plural(f, started, " minute", minutes)?;
|
||||
Self::plural(f, started, " second", seconds)?;
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------- [P2poolApi]
|
||||
pub struct P2poolApi {
|
||||
|
||||
}
|
||||
|
||||
impl P2poolApi {
|
||||
pub fn new() -> Self {
|
||||
Self {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------- [XmrigApi]
|
||||
pub struct XmrigApi {
|
||||
|
||||
}
|
||||
|
||||
impl XmrigApi {
|
||||
pub fn new() -> Self {
|
||||
Self {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------- The "helper" loop
|
||||
#[tokio::main]
|
||||
pub async fn helper() {
|
||||
thread::spawn(|| { loop {
|
||||
// 1. Check process signals, match, do action (start, kill, read)
|
||||
// 2. Spawn P2Pool API task
|
||||
// 3. Spawn XMRig HTTP API task
|
||||
// 4.
|
||||
// 5.
|
||||
// 6.
|
||||
// 7.
|
||||
// 8.
|
||||
// 9.
|
||||
// 10.
|
||||
// 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
|
||||
}});
|
||||
}
|
||||
|
|
32
src/main.rs
32
src/main.rs
|
@ -61,7 +61,7 @@ mod p2pool;
|
|||
mod xmrig;
|
||||
mod update;
|
||||
mod helper;
|
||||
use {ferris::*,constants::*,node::*,disk::*,status::*,update::*,gupax::*};
|
||||
use {ferris::*,constants::*,node::*,disk::*,status::*,update::*,gupax::*,helper::*};
|
||||
|
||||
//---------------------------------------------------------------------------------------------------- Struct + Impl
|
||||
// The state of the outer main [App].
|
||||
|
@ -98,13 +98,17 @@ pub struct App {
|
|||
// indicate if an error message needs to be displayed
|
||||
// (it takes up the whole screen with [error_msg] and buttons for ok/quit/etc)
|
||||
error_state: ErrorState,
|
||||
// Process State:
|
||||
// This holds everything related to the
|
||||
// child processes when starting P2Pool/XMRig.
|
||||
// Helper State:
|
||||
// This holds everything related to the data
|
||||
// processed by the "helper thread", including
|
||||
helper: Arc<Mutex<Helper>>,
|
||||
|
||||
// Fix-me.
|
||||
// These shouldn't exist
|
||||
// Just for debugging.
|
||||
p2pool: bool,
|
||||
xmrig: bool,
|
||||
// p2pool: Arc<Mutex<Process>>,
|
||||
// xmrig: Arc<Mutex<Process>>,
|
||||
|
||||
// State from [--flags]
|
||||
no_startup: bool,
|
||||
// Static stuff
|
||||
|
@ -133,7 +137,7 @@ impl App {
|
|||
}
|
||||
}
|
||||
|
||||
fn new() -> Self {
|
||||
fn new(now: Instant) -> Self {
|
||||
info!("Initializing App Struct...");
|
||||
let mut app = Self {
|
||||
tab: Tab::default(),
|
||||
|
@ -153,12 +157,17 @@ impl App {
|
|||
restart: Arc::new(Mutex::new(Restart::No)),
|
||||
diff: false,
|
||||
error_state: ErrorState::new(),
|
||||
helper: Arc::new(Mutex::new(Helper::new(now))),
|
||||
|
||||
// TODO
|
||||
// these p2pool/xmrig bools are here for debugging purposes
|
||||
// they represent the online/offline status.
|
||||
// fix this later when [Helper] is integrated.
|
||||
|
||||
p2pool: false,
|
||||
xmrig: false,
|
||||
// p2pool: Arc::new(Mutex::new(Process::new())),
|
||||
// xmrig: Arc::new(Mutex::new(Process::new())),
|
||||
no_startup: false,
|
||||
now: Instant::now(),
|
||||
now,
|
||||
exe: String::new(),
|
||||
dir: String::new(),
|
||||
resolution: Vec2::new(APP_DEFAULT_HEIGHT, APP_DEFAULT_WIDTH),
|
||||
|
@ -664,8 +673,7 @@ fn print_disk_file(path: &PathBuf) {
|
|||
fn main() {
|
||||
let now = Instant::now();
|
||||
init_logger(now);
|
||||
let mut app = App::new();
|
||||
app.now = now;
|
||||
let mut app = App::new(now);
|
||||
init_auto(&mut app);
|
||||
let initial_window_size = match app.state.gupax.simple {
|
||||
true => Some(Vec2::new(app.state.gupax.selected_width as f32, app.state.gupax.selected_height as f32)),
|
||||
|
|
Loading…
Reference in a new issue