Added better error handling.

This commit is contained in:
ClementTsang 2019-09-07 23:29:30 -04:00
parent 8da38c061d
commit ef2dc7e1b5
7 changed files with 52 additions and 26 deletions

View File

@ -1,3 +1,7 @@
use futures::{
future::{err, join_all, ok},
prelude::*,
};
use sysinfo::{System, SystemExt};
mod widgets;
@ -5,8 +9,14 @@ use widgets::{cpu, disks, mem, network, processes, temperature};
mod window;
fn push_if_valid<T : std::clone::Clone>(result : &Result<T, heim::Error>, vector_to_push_to : &mut Vec<T>) {
if let Ok(result) = result {
vector_to_push_to.push(result.clone());
}
}
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
async fn main() {
// Initialize
let refresh_interval = 1; // TODO: Make changing this possible!
let mut sys = System::new();
@ -18,31 +28,48 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
let mut list_of_timed_swap : Vec<mem::MemData> = Vec::new();
let mut list_of_timed_temperature : Vec<temperature::TimedTempData> = Vec::new();
let mut list_of_timed_network : Vec<network::TimedNetworkData> = Vec::new();
let mut list_of_processes = Vec::new();
let mut list_of_disks = Vec::new();
loop {
println!("Start data loop...");
sys.refresh_system();
sys.refresh_network();
// TODO: Get data, potentially store? Use a result to check!
let list_of_processes = processes::get_sorted_processes_list(processes::ProcessSorting::CPU, true).await;
for process in list_of_processes {
// What we want to do: For timed data, if there is an error, just do not add. For other data, just don't update!
list_of_timed_network.push(network::get_network_data(&sys));
if let Ok(process_vec) = processes::get_sorted_processes_list(processes::ProcessSorting::CPU, true).await {
list_of_processes = process_vec;
}
if let Ok(disks) = disks::get_disk_usage_list().await {
list_of_disks = disks;
}
push_if_valid(&disks::get_io_usage_list(false).await, &mut list_of_timed_io);
push_if_valid(&disks::get_io_usage_list(true).await, &mut list_of_timed_physical_io);
push_if_valid(&mem::get_mem_data_list().await, &mut list_of_timed_memory);
push_if_valid(&mem::get_swap_data_list().await, &mut list_of_timed_swap);
push_if_valid(&temperature::get_temperature_data().await, &mut list_of_timed_temperature);
push_if_valid(&cpu::get_cpu_data_list(&sys), &mut list_of_timed_cpu_packages);
println!("End data loop...");
// DEBUG - output results
for process in &list_of_processes {
println!(
"Process: {} with PID {}, CPU: {}%, MEM: {} MB",
process.command, process.pid, process.cpu_usage_percent, process.mem_usage_in_mb,
);
}
let list_of_disks = disks::get_disk_usage_list().await?;
for disk in list_of_disks {
for disk in &list_of_disks {
println!("{} is mounted on {}: {}/{} free.", disk.name, disk.mount_point, disk.avail_space as f64, disk.total_space as f64);
// TODO: Check if this is valid
}
list_of_timed_io.push(disks::get_io_usage_list(false).await?);
list_of_timed_physical_io.push(disks::get_io_usage_list(true).await?);
if !list_of_timed_io.is_empty() {
for io in list_of_timed_io.last().unwrap() {
println!("IO counter for {} at {:?}: {} writes, {} reads.", &io.mount_point, io.time, io.write_bytes, io.read_bytes);
@ -54,8 +81,6 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
}
}
list_of_timed_cpu_packages.push(cpu::get_cpu_data_list(&sys));
if !list_of_timed_cpu_packages.is_empty() {
let current_cpu_time = list_of_timed_cpu_packages.last().unwrap().time;
for cpu in &list_of_timed_cpu_packages.last().unwrap().processor_list {
@ -63,9 +88,6 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
}
}
list_of_timed_memory.push(mem::get_mem_data_list().await?);
list_of_timed_swap.push(mem::get_swap_data_list().await?);
if !list_of_timed_memory.is_empty() {
let current_mem = list_of_timed_memory.last().unwrap();
println!("Memory usage: {} out of {} is used, at {:?}", current_mem.mem_used, current_mem.mem_total, current_mem.time);
@ -76,7 +98,6 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
println!("Memory usage: {} out of {} is used, at {:?}", current_mem.mem_used, current_mem.mem_total, current_mem.time);
}
list_of_timed_temperature.push(temperature::get_temperature_data().await?);
if !list_of_timed_temperature.is_empty() {
let current_time = list_of_timed_temperature.last().unwrap().time;
for sensor in &list_of_timed_temperature.last().unwrap().temperature_vec {
@ -84,14 +105,12 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
}
}
list_of_timed_network.push(network::get_network_data(&sys));
if !list_of_timed_network.is_empty() {
let current_network = list_of_timed_network.last().unwrap();
println!("Network: {} rx, {} tx at {:?}", current_network.rx, current_network.tx, current_network.time);
}
// Send to drawing module
println!("End data loop...");
window::draw_terminal();
// Repeat on interval
@ -99,5 +118,4 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
}
// TODO: Exit on quit command/ctrl-c
Ok(())
}

View File

@ -1,16 +1,18 @@
use sysinfo::{ProcessorExt, System, SystemExt};
#[derive(Clone)]
pub struct CPUData {
pub cpu_name : Box<str>,
pub cpu_usage : u32,
}
#[derive(Clone)]
pub struct TimedCPUPackages {
pub processor_list : Vec<CPUData>,
pub time : std::time::SystemTime,
}
pub fn get_cpu_data_list(sys : &System) -> TimedCPUPackages {
pub fn get_cpu_data_list(sys : &System) -> Result<TimedCPUPackages, heim::Error> {
let cpu_data = sys.get_processor_list();
let mut cpu_vec = Vec::new();
@ -21,10 +23,10 @@ pub fn get_cpu_data_list(sys : &System) -> TimedCPUPackages {
})
}
TimedCPUPackages {
Ok(TimedCPUPackages {
processor_list : cpu_vec,
time : std::time::SystemTime::now(),
}
})
}
pub fn is_cpu_data_old() -> bool {

View File

@ -1,5 +1,6 @@
use heim_common::prelude::StreamExt;
#[derive(Clone)]
pub struct DiskInfo {
pub name : Box<str>,
pub mount_point : Box<str>,
@ -7,6 +8,7 @@ pub struct DiskInfo {
pub total_space : u64,
}
#[derive(Clone)]
pub struct TimedIOInfo {
pub mount_point : Box<str>,
pub read_bytes : u64,

View File

@ -1,5 +1,6 @@
use heim_common::units::information;
#[derive(Clone)]
pub struct MemData {
pub mem_total : u64,
pub mem_used : u64,

View File

@ -1,5 +1,6 @@
use sysinfo::{NetworkExt, System, SystemExt};
#[derive(Clone)]
pub struct TimedNetworkData {
pub rx : u64,
pub tx : u64,

View File

@ -11,7 +11,7 @@ pub enum ProcessSorting {
}
// Possible process info struct?
#[derive(Debug)]
#[derive(Clone, Debug)]
pub struct ProcessInfo {
pub pid : u32,
pub cpu_usage_percent : f32,
@ -49,7 +49,7 @@ async fn cpu_usage(process : heim::process::Process) -> heim::process::ProcessRe
Ok((process, usage_2 - usage_1))
}
pub async fn get_sorted_processes_list(sorting_method : ProcessSorting, reverse_order : bool) -> Vec<ProcessInfo> {
pub async fn get_sorted_processes_list(sorting_method : ProcessSorting, reverse_order : bool) -> Result<Vec<ProcessInfo>, heim::Error> {
let mut process_stream = heim::process::processes().map_ok(cpu_usage).try_buffer_unordered(std::usize::MAX);
// TODO: Group together processes
@ -76,5 +76,5 @@ pub async fn get_sorted_processes_list(sorting_method : ProcessSorting, reverse_
ProcessSorting::NAME => process_vector.sort_by(|a, b| get_ordering(&a.command, &b.command, reverse_order)),
}
process_vector
Ok(process_vector)
}

View File

@ -1,10 +1,12 @@
use heim_common::{prelude::StreamExt, units::thermodynamic_temperature};
#[derive(Clone)]
pub struct TempData {
pub component_name : Box<str>,
pub temperature : f32,
}
#[derive(Clone)]
pub struct TimedTempData {
pub temperature_vec : Vec<TempData>,
pub time : std::time::SystemTime,