yggdrasil/tasks/
sysinfo_sampler.rs1use std::sync::LazyLock;
11use std::time::Duration;
12
13use crate::models::system::SystemSnapshot;
14
15static SNAPSHOT: LazyLock<tokio::sync::RwLock<SystemSnapshot>> =
16 LazyLock::new(|| tokio::sync::RwLock::new(SystemSnapshot::default()));
17
18fn sample_interval() -> Duration {
20 let secs = std::env::var("SYSINFO_SAMPLE_SECS")
21 .ok()
22 .and_then(|s| s.parse::<f64>().ok())
23 .unwrap_or(0.5);
24 Duration::from_secs_f64(secs.max(0.05))
25}
26
27pub fn spawn_sampler() {
31 tokio::spawn(async move {
32 use sysinfo::{Disks, System};
33
34 let mut sys = System::new();
35 let interval = sample_interval();
36 sys.refresh_cpu_usage();
38 let disks = Disks::new_with_refreshed_list();
39
40 loop {
41 tokio::time::sleep(interval).await;
42 sys.refresh_cpu_usage();
43 sys.refresh_memory();
44 let load = System::load_average();
45
46 let (disk_total, disk_available) = disks
48 .list()
49 .iter()
50 .max_by_key(|d| d.total_space())
51 .map(|d| (d.total_space(), d.available_space()))
52 .unwrap_or((0, 0));
53
54 let snap = SystemSnapshot {
55 cpu_usage: sys.global_cpu_usage(),
56 load_avg_1: load.one,
57 total_memory: sys.total_memory(),
58 used_memory: sys.used_memory(),
59 disk_total,
60 disk_available,
61 os_name: System::long_os_version().unwrap_or_default(),
62 kernel_version: System::kernel_version().unwrap_or_default(),
63 uptime_secs: System::uptime(),
64 };
65 *SNAPSHOT.write().await = snap;
66 }
67 });
68}
69
70pub async fn read_snapshot() -> SystemSnapshot {
72 SNAPSHOT.read().await.clone()
73}