//! System info use std::{sync::Mutex, time::Duration}; use anyhow::Context; use sysinfo::{CpuRefreshKind, SystemExt}; use crate::debian; pub struct Info { system: sysinfo::System, updates: Vec, } impl Info { pub fn new() -> Self { Self { system: sysinfo::System::new(), updates: Vec::new(), } } pub fn refresh_resources(&mut self) { self.system.refresh_specifics( sysinfo::RefreshKind::new() .with_disks_list() .with_memory() .with_cpu(CpuRefreshKind::new().with_cpu_usage()), ); } pub fn refresh_updates(&mut self) -> anyhow::Result<()> { debian::update_package_index().context("while fetching the package index")?; let updates = debian::get_available_updates().context("while fetching available updates")?; self.updates = updates; Ok(()) } pub fn system(&self) -> &sysinfo::System { &self.system } pub fn updates(&self) -> &Vec { &self.updates } } impl Default for Info { fn default() -> Self { Self::new() } } /// Spawns a new thread that forever gathers system information. pub fn spawn_info_subsystem() -> &'static Mutex { const REFRESH_RESOURCES_INTERVAL: Duration = Duration::from_secs(5); const REFRESH_UPDATES_INTERVAL: Duration = Duration::from_secs(3600); let info = Box::new(Mutex::new(Info::new())); let info = Box::leak(info); std::thread::spawn(|| loop { tracing::debug!("refreshing system resources"); #[allow(clippy::mut_mutex_lock)] info.lock().unwrap().refresh_resources(); std::thread::sleep(REFRESH_RESOURCES_INTERVAL); }); std::thread::spawn(|| loop { tracing::debug!("refreshing available system updates"); #[allow(clippy::mut_mutex_lock)] if let Err(err) = info.lock().unwrap().refresh_updates() { tracing::warn!(?err, "failed to refresh updates"); } std::thread::sleep(REFRESH_UPDATES_INTERVAL); }); info }