dotfiles/agent/src/system/info.rs

88 lines
2.1 KiB
Rust
Raw Normal View History

//! 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<String>,
}
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<String> {
&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<Info> {
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
}