Moved CPU over

This commit is contained in:
ClementTsang 2020-01-26 20:14:14 -05:00
parent c5cd431e2e
commit 57aa15978c
7 changed files with 104 additions and 131 deletions

View File

@ -639,15 +639,8 @@ impl App {
self.currently_selected_disk_position = self.data.list_of_disks.len() as i64 - 1 self.currently_selected_disk_position = self.data.list_of_disks.len() as i64 - 1
} }
ApplicationPosition::Cpu => { ApplicationPosition::Cpu => {
if let Some(cpu_package) = self.data.list_of_cpu_packages.last() { self.currently_selected_cpu_table_position =
if self.show_average_cpu { self.canvas_data.cpu_data.len() as i64 - 1;
self.currently_selected_cpu_table_position =
cpu_package.cpu_vec.len() as i64;
} else {
self.currently_selected_cpu_table_position =
cpu_package.cpu_vec.len() as i64 - 1;
}
}
} }
_ => {} _ => {}
} }
@ -685,17 +678,11 @@ impl App {
} }
fn change_cpu_table_position(&mut self, num_to_change_by: i64) { fn change_cpu_table_position(&mut self, num_to_change_by: i64) {
if let Some(cpu_package) = self.data.list_of_cpu_packages.last() { if self.currently_selected_cpu_table_position + num_to_change_by >= 0
if self.currently_selected_cpu_table_position + num_to_change_by >= 0 && self.currently_selected_cpu_table_position + num_to_change_by
&& self.currently_selected_cpu_table_position + num_to_change_by < self.canvas_data.cpu_data.len() as i64
< if self.show_average_cpu { {
cpu_package.cpu_vec.len() self.currently_selected_cpu_table_position += num_to_change_by;
} else {
cpu_package.cpu_vec.len() - 1
} as i64
{
self.currently_selected_cpu_table_position += num_to_change_by;
}
} }
} }

View File

@ -25,7 +25,7 @@ fn push_if_valid<T: std::clone::Clone>(result: &Result<T>, vector_to_push: &mut
#[derive(Clone, Debug)] #[derive(Clone, Debug)]
pub struct Data { pub struct Data {
pub list_of_cpu_packages: Vec<cpu::CPUPackage>, pub cpu: cpu::CPUHarvest,
pub list_of_io: Vec<disks::IOPackage>, pub list_of_io: Vec<disks::IOPackage>,
pub memory: mem::MemHarvest, pub memory: mem::MemHarvest,
pub swap: mem::MemHarvest, pub swap: mem::MemHarvest,
@ -40,7 +40,7 @@ pub struct Data {
impl Default for Data { impl Default for Data {
fn default() -> Self { fn default() -> Self {
Data { Data {
list_of_cpu_packages: Vec::default(), cpu: cpu::CPUHarvest::default(),
list_of_io: Vec::default(), list_of_io: Vec::default(),
memory: mem::MemHarvest::default(), memory: mem::MemHarvest::default(),
swap: mem::MemHarvest::default(), swap: mem::MemHarvest::default(),
@ -56,7 +56,6 @@ impl Default for Data {
impl Data { impl Data {
pub fn first_run_cleanup(&mut self) { pub fn first_run_cleanup(&mut self) {
self.list_of_cpu_packages = Vec::new();
self.list_of_io = Vec::new(); self.list_of_io = Vec::new();
self.list_of_temperature_sensor = Vec::new(); self.list_of_temperature_sensor = Vec::new();
self.list_of_processes = Vec::new(); self.list_of_processes = Vec::new();
@ -66,6 +65,7 @@ impl Data {
self.network.first_run_cleanup(); self.network.first_run_cleanup();
self.memory = mem::MemHarvest::default(); self.memory = mem::MemHarvest::default();
self.swap = mem::MemHarvest::default(); self.swap = mem::MemHarvest::default();
self.cpu = cpu::CPUHarvest::default();
} }
} }
@ -112,6 +112,7 @@ impl DataState {
self.sys.refresh_all(); self.sys.refresh_all();
self.mem_total_kb = self.sys.get_total_memory(); self.mem_total_kb = self.sys.get_total_memory();
futures::executor::block_on(self.update_data()); futures::executor::block_on(self.update_data());
std::thread::sleep(std::time::Duration::from_millis(250));
self.data.first_run_cleanup(); self.data.first_run_cleanup();
} }
@ -145,11 +146,10 @@ impl DataState {
self.data.swap = swap; self.data.swap = swap;
} }
// CPU
self.data.cpu = cpu::get_cpu_data_list(&self.sys);
// What we want to do: For timed data, if there is an error, just do not add. For other data, just don't update! // What we want to do: For timed data, if there is an error, just do not add. For other data, just don't update!
push_if_valid(
&cpu::get_cpu_data_list(&self.sys, &current_instant),
&mut self.data.list_of_cpu_packages,
);
set_if_valid( set_if_valid(
&processes::get_sorted_processes_list( &processes::get_sorted_processes_list(
&self.sys, &self.sys,
@ -192,17 +192,6 @@ impl DataState {
for stale in stale_list { for stale in stale_list {
self.prev_pid_stats.remove(&stale); self.prev_pid_stats.remove(&stale);
} }
self.data.list_of_cpu_packages = self
.data
.list_of_cpu_packages
.iter()
.cloned()
.filter(|entry| {
clean_instant.duration_since(entry.instant).as_secs() <= self.stale_max_seconds
})
.collect::<Vec<_>>();
self.data.list_of_io = self self.data.list_of_io = self
.data .data
.list_of_io .list_of_io

View File

@ -1,33 +1,26 @@
use std::time::Instant;
use sysinfo::{ProcessorExt, System, SystemExt}; use sysinfo::{ProcessorExt, System, SystemExt};
#[derive(Debug, Clone)] #[derive(Default, Debug, Clone)]
pub struct CPUData { pub struct CPUData {
pub cpu_name: Box<str>, pub cpu_name: String,
pub cpu_usage: f64, pub cpu_usage: f64,
} }
#[derive(Debug, Clone)] #[derive(Default, Debug, Clone)]
pub struct CPUPackage { pub struct CPUHarvest {
pub cpu_vec: Vec<CPUData>, pub cpu_vec: Vec<CPUData>,
pub instant: Instant,
} }
pub fn get_cpu_data_list( pub fn get_cpu_data_list(sys: &System) -> CPUHarvest {
sys: &System, curr_time: &Instant,
) -> crate::utils::error::Result<CPUPackage> {
let cpu_data = sys.get_processor_list(); let cpu_data = sys.get_processor_list();
let mut cpu_vec = Vec::new(); let mut cpu_vec = Vec::new();
for cpu in cpu_data { for cpu in cpu_data {
cpu_vec.push(CPUData { cpu_vec.push(CPUData {
cpu_name: Box::from(cpu.get_name()), cpu_name: cpu.get_name().to_string(),
cpu_usage: f64::from(cpu.get_cpu_usage()) * 100_f64, cpu_usage: f64::from(cpu.get_cpu_usage()) * 100_f64,
}); });
} }
Ok(CPUPackage { CPUHarvest { cpu_vec }
cpu_vec,
instant: *curr_time,
})
} }

View File

@ -1,4 +1,4 @@
use crate::data_harvester::{mem, network, Data}; use crate::data_harvester::{cpu, mem, network, Data};
/// In charge of cleaning and managing data. I couldn't think of a better /// In charge of cleaning and managing data. I couldn't think of a better
/// name for the file. /// name for the file.
use std::time::Instant; use std::time::Instant;
@ -12,7 +12,7 @@ pub type JoinedDataPoints = (Value, Vec<(TimeOffset, Value)>);
pub struct TimedData { pub struct TimedData {
pub rx_data: JoinedDataPoints, pub rx_data: JoinedDataPoints,
pub tx_data: JoinedDataPoints, pub tx_data: JoinedDataPoints,
pub cpu_data: JoinedDataPoints, pub cpu_data: Vec<JoinedDataPoints>,
pub mem_data: JoinedDataPoints, pub mem_data: JoinedDataPoints,
pub swap_data: JoinedDataPoints, pub swap_data: JoinedDataPoints,
pub temp_data: JoinedDataPoints, pub temp_data: JoinedDataPoints,
@ -35,7 +35,7 @@ pub struct DataCollection {
pub network_harvest: network::NetworkHarvest, pub network_harvest: network::NetworkHarvest,
pub memory_harvest: mem::MemHarvest, pub memory_harvest: mem::MemHarvest,
pub swap_harvest: mem::MemHarvest, pub swap_harvest: mem::MemHarvest,
// pub process_data: ProcessData, pub cpu_harvest: cpu::CPUHarvest,
} }
impl Default for DataCollection { impl Default for DataCollection {
@ -46,7 +46,7 @@ impl Default for DataCollection {
network_harvest: network::NetworkHarvest::default(), network_harvest: network::NetworkHarvest::default(),
memory_harvest: mem::MemHarvest::default(), memory_harvest: mem::MemHarvest::default(),
swap_harvest: mem::MemHarvest::default(), swap_harvest: mem::MemHarvest::default(),
// process_data: ProcessData::default(), cpu_harvest: cpu::CPUHarvest::default(),
} }
} }
} }
@ -64,6 +64,9 @@ impl DataCollection {
// Memory and Swap // Memory and Swap
self.eat_memory_and_swap(&harvested_data, &harvested_time, &mut new_entry); self.eat_memory_and_swap(&harvested_data, &harvested_time, &mut new_entry);
// CPU
self.eat_cpu(&harvested_data, &harvested_time, &mut new_entry);
// And we're done eating. // And we're done eating.
self.current_instant = harvested_time; self.current_instant = harvested_time;
self.timed_data_vec.push((harvested_time, new_entry)); self.timed_data_vec.push((harvested_time, new_entry));
@ -137,6 +140,31 @@ impl DataCollection {
// In addition copy over latest data for easy reference // In addition copy over latest data for easy reference
self.network_harvest = harvested_data.network.clone(); self.network_harvest = harvested_data.network.clone();
} }
fn eat_cpu(
&mut self, harvested_data: &Data, harvested_time: &Instant, new_entry: &mut TimedData,
) {
// Note this only pre-calculates the data points - the names will be
// within the local copy of cpu_harvest. Since it's all sequential
// it probably doesn't matter anyways.
for (itx, cpu) in harvested_data.cpu.cpu_vec.iter().enumerate() {
let cpu_joining_pts = if let Some((time, last_pt)) = self.timed_data_vec.last() {
generate_joining_points(
&time,
last_pt.cpu_data[itx].0,
&harvested_time,
cpu.cpu_usage,
)
} else {
Vec::new()
};
let cpu_pt = (cpu.cpu_usage, cpu_joining_pts);
new_entry.cpu_data.push(cpu_pt);
}
self.cpu_harvest = harvested_data.cpu.clone();
}
} }
pub fn generate_joining_points( pub fn generate_joining_points(
@ -151,13 +179,13 @@ pub fn generate_joining_points(
// Let's generate... about this many points! // Let's generate... about this many points!
let num_points = std::cmp::min( let num_points = std::cmp::min(
std::cmp::max( std::cmp::max(
(value_difference.abs() / (time_difference + 0.0001) * 1000.0) as u64, (value_difference.abs() / (time_difference + 0.0001) * 500.0) as u64,
100, 100,
), ),
1000, 500,
); );
for itx in 0..num_points { for itx in (0..num_points).step_by(1) {
points.push(( points.push((
time_difference - (itx as f64 / num_points as f64 * time_difference), time_difference - (itx as f64 / num_points as f64 * time_difference),
start_y + (itx as f64 / num_points as f64 * value_difference), start_y + (itx as f64 / num_points as f64 * value_difference),

View File

@ -391,7 +391,7 @@ fn draw_cpu_graph<B: backend::Backend>(f: &mut Frame<B>, app_state: &app::App, d
// CPU usage graph // CPU usage graph
let x_axis: Axis<String> = Axis::default() let x_axis: Axis<String> = Axis::default()
.style(Style::default().fg(GRAPH_COLOUR)) .style(Style::default().fg(GRAPH_COLOUR))
.bounds([0.0, constants::TIME_STARTS_FROM as f64 * 10.0]); .bounds([0.0, constants::TIME_STARTS_FROM as f64]);
let y_axis = Axis::default() let y_axis = Axis::default()
.style(Style::default().fg(GRAPH_COLOUR)) .style(Style::default().fg(GRAPH_COLOUR))
.bounds([-0.5, 100.5]) .bounds([-0.5, 100.5])

View File

@ -9,7 +9,6 @@ use crate::{
}; };
use constants::*; use constants::*;
use regex::Regex; use regex::Regex;
use std::time::Instant;
#[derive(Default, Debug)] #[derive(Default, Debug)]
pub struct ConvertedNetworkData { pub struct ConvertedNetworkData {
@ -238,78 +237,48 @@ fn return_mapped_process(process: &data_harvester::processes::ProcessData) -> Co
} }
pub fn update_cpu_data_points( pub fn update_cpu_data_points(
show_avg_cpu: bool, app_data: &data_harvester::Data, show_avg_cpu: bool, current_data: &data_janitor::DataCollection,
) -> Vec<ConvertedCpuData> { ) -> Vec<ConvertedCpuData> {
let mut cpu_data_vector: Vec<ConvertedCpuData> = Vec::new(); let mut cpu_data_vector: Vec<ConvertedCpuData> = Vec::new();
let mut cpu_collection: Vec<Vec<CpuPoint>> = Vec::new(); let current_time = current_data.current_instant;
let cpu_listing_offset = if show_avg_cpu { 0 } else { 1 };
if !app_data.list_of_cpu_packages.is_empty() { for (time, data) in &current_data.timed_data_vec {
// I'm sorry for the following if statement but I couldn't be bothered here... let time_from_start: f64 = (TIME_STARTS_FROM as f64
for cpu_num in (if show_avg_cpu { 0 } else { 1 }) - current_time.duration_since(*time).as_millis() as f64)
..app_data.list_of_cpu_packages.last().unwrap().cpu_vec.len() .floor();
{
let mut this_cpu_data: Vec<CpuPoint> = Vec::new();
for data in &app_data.list_of_cpu_packages { for (itx, cpu) in data.cpu_data.iter().enumerate() {
let current_time = Instant::now(); if !show_avg_cpu && itx == 0 {
let current_cpu_usage = data.cpu_vec[cpu_num].cpu_usage; continue;
let new_entry = CpuPoint {
time: ((TIME_STARTS_FROM as f64
- current_time.duration_since(data.instant).as_millis() as f64)
* 10_f64)
.floor(),
usage: current_cpu_usage,
};
// Now, inject our joining points...
if let Some(previous_element_data) = this_cpu_data.last().cloned() {
for idx in 0..50 {
this_cpu_data.push(CpuPoint {
time: previous_element_data.time
+ ((new_entry.time - previous_element_data.time) / 50.0
* f64::from(idx)),
usage: previous_element_data.usage
+ ((new_entry.usage - previous_element_data.usage) / 50.0
* f64::from(idx)),
});
}
}
this_cpu_data.push(new_entry);
} }
cpu_collection.push(this_cpu_data); // Check if the vector exists yet
} let itx_offset = itx - cpu_listing_offset;
if cpu_data_vector.len() <= itx_offset {
cpu_data_vector.push(ConvertedCpuData::default());
cpu_data_vector[itx_offset].cpu_name = if show_avg_cpu && itx_offset == 0 {
"AVG".to_string()
} else {
current_data.cpu_harvest.cpu_vec[itx]
.cpu_name
.to_uppercase()
};
}
// Finally, add it all onto the end //Insert joiner points
for (i, data) in cpu_collection.iter().enumerate() { for &(joiner_offset, joiner_val) in &cpu.1 {
if !app_data.list_of_cpu_packages.is_empty() { let offset_time = time_from_start - joiner_offset as f64;
// Commented out: this version includes the percentage in the label... cpu_data_vector[itx_offset].cpu_data.push(CpuPoint {
// cpu_data_vector.push(( time: offset_time,
// // + 1 to skip total CPU if show_avg_cpu is false usage: joiner_val,
// format!(
// "{:4}: ",
// &*(app_data.list_of_cpu_packages.last().unwrap().cpu_vec[i + if show_avg_cpu { 0 } else { 1 }].cpu_name)
// )
// .to_uppercase() + &format!("{:3}%", (data.last().unwrap_or(&(0_f64, 0_f64)).1.round() as u64)),
// data.clone(),
// ))
cpu_data_vector.push(ConvertedCpuData {
cpu_name: format!(
"{} ",
if show_avg_cpu && i == 0 {
"AVG"
} else {
&*(app_data.list_of_cpu_packages.last().unwrap().cpu_vec
[i + if show_avg_cpu { 0 } else { 1 }]
.cpu_name)
}
)
.to_uppercase(),
cpu_data: data.clone(),
}); });
} }
cpu_data_vector[itx_offset].cpu_data.push(CpuPoint {
time: time_from_start,
usage: cpu.0,
});
} }
} }

View File

@ -264,16 +264,13 @@ fn main() -> error::Result<()> {
_ => {} _ => {}
}, },
Event::Update(data) => { Event::Update(data) => {
// NOTE TO SELF - data is refreshed into app state HERE! That means, if it is
// frozen, then, app.data is never refreshed, until unfrozen!
if !app.is_frozen { if !app.is_frozen {
app.data_collection.eat_data(&data); app.data_collection.eat_data(&data);
app.data = *data; // TODO: [OPT] remove this
app.data = *data; // Convert all data into tui-compliant components
handle_process_sorting(&mut app); // Network
// Convert all data into tui components
let network_data = convert_network_data_points(&app.data_collection); let network_data = convert_network_data_points(&app.data_collection);
app.canvas_data.network_data_rx = network_data.rx; app.canvas_data.network_data_rx = network_data.rx;
app.canvas_data.network_data_tx = network_data.tx; app.canvas_data.network_data_tx = network_data.tx;
@ -281,16 +278,26 @@ fn main() -> error::Result<()> {
app.canvas_data.tx_display = network_data.tx_display; app.canvas_data.tx_display = network_data.tx_display;
app.canvas_data.total_rx_display = network_data.total_rx_display; app.canvas_data.total_rx_display = network_data.total_rx_display;
app.canvas_data.total_tx_display = network_data.total_tx_display; app.canvas_data.total_tx_display = network_data.total_tx_display;
// Disk
app.canvas_data.disk_data = update_disk_row(&app.data); app.canvas_data.disk_data = update_disk_row(&app.data);
// Temperatures
app.canvas_data.temp_sensor_data = app.canvas_data.temp_sensor_data =
update_temp_row(&app.data, &app.temperature_type); update_temp_row(&app.data, &app.temperature_type);
// Memory
app.canvas_data.mem_data = update_mem_data_points(&app.data_collection); app.canvas_data.mem_data = update_mem_data_points(&app.data_collection);
app.canvas_data.swap_data = update_swap_data_points(&app.data_collection); app.canvas_data.swap_data = update_swap_data_points(&app.data_collection);
let memory_and_swap_labels = update_mem_labels(&app.data_collection); let memory_and_swap_labels = update_mem_labels(&app.data_collection);
app.canvas_data.mem_label = memory_and_swap_labels.0; app.canvas_data.mem_label = memory_and_swap_labels.0;
app.canvas_data.swap_label = memory_and_swap_labels.1; app.canvas_data.swap_label = memory_and_swap_labels.1;
// CPU
app.canvas_data.cpu_data = app.canvas_data.cpu_data =
update_cpu_data_points(app.show_average_cpu, &app.data); update_cpu_data_points(app.show_average_cpu, &app.data_collection);
// Processes
handle_process_sorting(&mut app);
} }
} }
} }