//! Shared agent state: sysinfo handles and hot JSON cache. #[cfg(target_os = "linux")] use std::collections::HashMap; use std::sync::atomic::{AtomicBool, AtomicUsize}; use std::sync::Arc; use sysinfo::{Components, Disks, Networks, System}; use tokio::sync::Mutex; pub type SharedSystem = Arc>; pub type SharedComponents = Arc>; pub type SharedDisks = Arc>; pub type SharedNetworks = Arc>; #[cfg(target_os = "linux")] #[derive(Default)] pub struct ProcCpuTracker { pub last_total: u64, pub last_per_pid: HashMap, } #[derive(Clone)] pub struct AppState { pub sys: SharedSystem, pub components: SharedComponents, pub disks: SharedDisks, pub networks: SharedNetworks, // For correct per-process CPU% using /proc deltas (Linux only path uses this tracker) #[cfg(target_os = "linux")] pub proc_cpu: Arc>, // Connection tracking (to allow future idle sleeps if desired) pub client_count: Arc, pub auth_token: Option, // GPU negative cache (probe once). gpu_checked=true after first attempt; gpu_present reflects result. pub gpu_checked: Arc, pub gpu_present: Arc, } impl AppState { pub fn new() -> Self { let sys = System::new(); let components = Components::new_with_refreshed_list(); let disks = Disks::new_with_refreshed_list(); let networks = Networks::new_with_refreshed_list(); Self { sys: Arc::new(Mutex::new(sys)), components: Arc::new(Mutex::new(components)), disks: Arc::new(Mutex::new(disks)), networks: Arc::new(Mutex::new(networks)), #[cfg(target_os = "linux")] proc_cpu: Arc::new(Mutex::new(ProcCpuTracker::default())), client_count: Arc::new(AtomicUsize::new(0)), auth_token: std::env::var("SOCKTOP_TOKEN") .ok() .filter(|s| !s.is_empty()), gpu_checked: Arc::new(AtomicBool::new(false)), gpu_present: Arc::new(AtomicBool::new(false)), } } }