Skip to content

Commit

Permalink
fear: change refresh interval with hotkeys #16
Browse files Browse the repository at this point in the history
  • Loading branch information
vladkens committed Dec 20, 2024
1 parent bdfb15a commit 8172486
Show file tree
Hide file tree
Showing 6 changed files with 73 additions and 17 deletions.
12 changes: 12 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -19,4 +19,5 @@ libc = "0.2.168"
num-traits = "0.2.19"
ratatui = { version = "0.29.0", features = ["serde"] }
serde = { version = "1.0.216", features = ["derive"] }
serde-inline-default = "0.2.3"
serde_json = "1.0.133"
31 changes: 24 additions & 7 deletions src/app.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
use std::sync::{Arc, RwLock};
use std::{io::stdout, time::Instant};
use std::{sync::mpsc, time::Duration};

Expand Down Expand Up @@ -121,6 +122,8 @@ enum Event {
Update(Metrics),
ChangeColor,
ChangeView,
IncInterval,
DecInterval,
Tick,
Quit,
}
Expand All @@ -131,6 +134,9 @@ fn handle_key_event(key: &event::KeyEvent, tx: &mpsc::Sender<Event>) -> WithErro
KeyCode::Char('c') if key.modifiers == KeyModifiers::CONTROL => Ok(tx.send(Event::Quit)?),
KeyCode::Char('c') => Ok(tx.send(Event::ChangeColor)?),
KeyCode::Char('v') => Ok(tx.send(Event::ChangeView)?),
KeyCode::Char('+') => Ok(tx.send(Event::IncInterval)?),
KeyCode::Char('=') => Ok(tx.send(Event::IncInterval)?), // fallback to press without shift
KeyCode::Char('-') => Ok(tx.send(Event::DecInterval)?),
_ => Ok(()),
}
}
Expand All @@ -157,17 +163,16 @@ fn run_inputs_thread(tx: mpsc::Sender<Event>, tick: u64) {
});
}

fn run_sampler_thread(tx: mpsc::Sender<Event>, interval: u64) {
let interval = interval.max(100).min(10000);

fn run_sampler_thread(tx: mpsc::Sender<Event>, msec: Arc<RwLock<u32>>) {
std::thread::spawn(move || {
let mut sampler = Sampler::new().unwrap();

// Send initial metrics
tx.send(Event::Update(sampler.get_metrics(100).unwrap())).unwrap();

loop {
tx.send(Event::Update(sampler.get_metrics(interval).unwrap())).unwrap();
let msec = *msec.read().unwrap();
tx.send(Event::Update(sampler.get_metrics(msec).unwrap())).unwrap();
}
});
}
Expand Down Expand Up @@ -372,7 +377,7 @@ impl App {
};

let block = self.title_block(&label_l, &label_r);
let usage = " Press 'q' to quit, 'c' – color, 'v' – view ";
let usage = format!(" 'q' quit, 'c' – color, 'v' – view | -/+ {}ms ", self.cfg.interval);
let block = block.title_bottom(Line::from(usage).right_aligned());
let iarea = block.inner(rows[1]);
f.render_widget(block, rows[1]);
Expand All @@ -387,10 +392,14 @@ impl App {
f.render_widget(self.get_power_block("ANE", &self.ane_power, 0.0), ha[2]);
}

pub fn run_loop(&mut self, interval: u64) -> WithError<()> {
pub fn run_loop(&mut self, interval: Option<u32>) -> WithError<()> {
// use from arg if provided, otherwise use config restored value
self.cfg.interval = interval.unwrap_or(self.cfg.interval).max(100).min(10_000);
let msec = Arc::new(RwLock::new(self.cfg.interval));

let (tx, rx) = mpsc::channel::<Event>();
run_inputs_thread(tx.clone(), 250);
run_sampler_thread(tx.clone(), interval);
run_sampler_thread(tx.clone(), msec.clone());

let mut term = enter_term();

Expand All @@ -402,6 +411,14 @@ impl App {
Event::Update(data) => self.update_metrics(data),
Event::ChangeColor => self.cfg.next_color(),
Event::ChangeView => self.cfg.next_view_type(),
Event::IncInterval => {
self.cfg.inc_interval();
*msec.write().unwrap() = self.cfg.interval;
}
Event::DecInterval => {
self.cfg.dec_interval();
*msec.write().unwrap() = self.cfg.interval;
}
_ => {}
}
}
Expand Down
28 changes: 24 additions & 4 deletions src/config.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
use ratatui::style::Color;
use serde::{Deserialize, Serialize};
use serde_inline_default::serde_inline_default;

const COLORS_OPTIONS: [Color; 7] =
[Color::Green, Color::Yellow, Color::Red, Color::Blue, Color::Magenta, Color::Cyan, Color::Reset];
Expand All @@ -10,10 +11,23 @@ pub enum ViewType {
Gauge,
}

#[serde_inline_default]
#[derive(Debug, Serialize, Deserialize)]
pub struct Config {
#[serde_inline_default(ViewType::Sparkline)]
pub view_type: ViewType,

#[serde_inline_default(COLORS_OPTIONS[0])]
pub color: Color,

#[serde_inline_default(1000)]
pub interval: u32,
}

impl Default for Config {
fn default() -> Self {
serde_json::from_str("{}").unwrap()
}
}

impl Config {
Expand Down Expand Up @@ -72,10 +86,16 @@ impl Config {
};
self.save();
}
}

impl Default for Config {
fn default() -> Self {
Self { color: COLORS_OPTIONS[0], view_type: ViewType::Sparkline }
pub fn dec_interval(&mut self) {
let step = 250;
self.interval = ((self.interval.saturating_sub(step) + step - 1) / step * step).max(step);
self.save();
}

pub fn inc_interval(&mut self) {
let step = 250;
self.interval = (self.interval.saturating_add(step) / step * step).min(10_000);
self.save();
}
}
14 changes: 10 additions & 4 deletions src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ mod metrics;
mod sources;

use app::App;
use clap::{Parser, Subcommand};
use clap::{parser::ValueSource, CommandFactory, Parser, Subcommand};
use metrics::Sampler;
use std::error::Error;

Expand Down Expand Up @@ -33,20 +33,19 @@ struct Cli {

/// Update interval in milliseconds
#[arg(short, long, default_value_t = 1000)]
interval: u64,
interval: u32,
}

fn main() -> Result<(), Box<dyn Error>> {
let args = Cli::parse();
let msec = args.interval.max(100);

match &args.command {
Some(Commands::Pipe { samples }) => {
let mut sampler = Sampler::new()?;
let mut counter = 0u32;

loop {
let doc = sampler.get_metrics(msec)?;
let doc = sampler.get_metrics(args.interval.max(100))?;
let doc = serde_json::to_string(&doc)?;
println!("{}", doc);

Expand All @@ -59,6 +58,13 @@ fn main() -> Result<(), Box<dyn Error>> {
Some(Commands::Debug) => debug::print_debug()?,
_ => {
let mut app = App::new()?;

let matches = Cli::command().get_matches();
let msec = match matches.value_source("interval") {
Some(ValueSource::CommandLine) => Some(args.interval),
_ => None,
};

app.run_loop(msec)?;
}
}
Expand Down
4 changes: 2 additions & 2 deletions src/metrics.rs
Original file line number Diff line number Diff line change
Expand Up @@ -216,13 +216,13 @@ impl Sampler {
Ok(val)
}

pub fn get_metrics(&mut self, duration: u64) -> WithError<Metrics> {
pub fn get_metrics(&mut self, duration: u32) -> WithError<Metrics> {
let measures: usize = 4;
let mut results: Vec<Metrics> = Vec::with_capacity(measures);

// do several samples to smooth metrics
// see: https://github.com/vladkens/macmon/issues/10
for (sample, dt) in self.ior.get_samples(duration, measures) {
for (sample, dt) in self.ior.get_samples(duration as u64, measures) {
let mut ecpu_usages = Vec::new();
let mut pcpu_usages = Vec::new();
let mut rs = Metrics::default();
Expand Down

0 comments on commit 8172486

Please sign in to comment.