use std::{sync::RwLock, time::Duration};
use tokio_util::sync::CancellationToken;
use tracing::debug;
use wayle_core::Property;
use crate::{
builder::SysinfoServiceBuilder,
polling,
types::{CpuData, DiskData, MemoryData, NetworkData},
};
#[derive(Debug)]
pub struct SysinfoService {
pub(crate) cancellation_token: CancellationToken,
pub(crate) cpu_token: RwLock<CancellationToken>,
pub(crate) memory_token: RwLock<CancellationToken>,
pub(crate) disk_token: RwLock<CancellationToken>,
pub(crate) network_token: RwLock<CancellationToken>,
pub(crate) cpu_interval: RwLock<Duration>,
pub(crate) cpu_temp_sensor: RwLock<String>,
pub cpu: Property<CpuData>,
pub memory: Property<MemoryData>,
pub disks: Property<Vec<DiskData>>,
pub network: Property<Vec<NetworkData>>,
}
impl SysinfoService {
pub fn builder() -> SysinfoServiceBuilder {
SysinfoServiceBuilder::new()
}
pub fn set_cpu_interval(&self, interval: Duration) {
debug!(?interval, "Updating CPU polling interval");
if let Ok(mut guard) = self.cpu_interval.write() {
*guard = interval;
}
self.restart_cpu_polling();
}
pub fn set_cpu_temp_sensor(&self, sensor: &str) {
debug!(?sensor, "Updating CPU temperature sensor");
if let Ok(mut guard) = self.cpu_temp_sensor.write() {
*guard = sensor.to_owned();
}
self.restart_cpu_polling();
}
fn restart_cpu_polling(&self) {
let interval = self.cpu_interval.read().map(|g| *g).unwrap_or_default();
let sensor = self
.cpu_temp_sensor
.read()
.map(|g| g.clone())
.unwrap_or_default();
let new_token = self.cancellation_token.child_token();
if let Ok(mut guard) = self.cpu_token.write() {
guard.cancel();
polling::cpu::spawn(new_token.clone(), self.cpu.clone(), interval, sensor);
*guard = new_token;
}
}
pub fn set_memory_interval(&self, interval: Duration) {
debug!(?interval, "Updating memory polling interval");
let new_token = self.cancellation_token.child_token();
if let Ok(mut guard) = self.memory_token.write() {
guard.cancel();
polling::memory::spawn(new_token.clone(), self.memory.clone(), interval);
*guard = new_token;
}
}
pub fn set_disk_interval(&self, interval: Duration) {
debug!(?interval, "Updating disk polling interval");
let new_token = self.cancellation_token.child_token();
if let Ok(mut guard) = self.disk_token.write() {
guard.cancel();
polling::disk::spawn(new_token.clone(), self.disks.clone(), interval);
*guard = new_token;
}
}
pub fn set_network_interval(&self, interval: Duration) {
debug!(?interval, "Updating network polling interval");
let new_token = self.cancellation_token.child_token();
if let Ok(mut guard) = self.network_token.write() {
guard.cancel();
polling::network::spawn(new_token.clone(), self.network.clone(), interval);
*guard = new_token;
}
}
}
impl Drop for SysinfoService {
fn drop(&mut self) {
self.cancellation_token.cancel();
}
}