use std::time::{Duration, Instant};
use tokio_util::sync::CancellationToken;
use super::server::LspServer;
pub struct SettleSample {
pub timestamp: Instant,
pub server: String,
pub pid: u32,
pub ppid: u32,
pub delta_pfc: u64,
pub delta_utime: u64,
pub delta_stime: u64,
pub in_progress_count: u32,
pub process_count: usize,
}
pub trait SettleSink: Send {
fn record(&mut self, sample: &SettleSample) -> bool;
}
#[allow(
clippy::similar_names,
reason = "delta_utime/delta_stime are standard counter names"
)]
pub async fn settle_loop(
tree_monitor: &mut catenary_proc::TreeMonitor,
server: &LspServer,
server_name: &str,
interval: Duration,
sink: &mut dyn SettleSink,
cancel: CancellationToken,
) {
loop {
tokio::select! {
() = tokio::time::sleep(interval) => {}
() = cancel.cancelled() => { return; }
}
let snapshot = tree_monitor.sample();
let in_progress_count = server.in_progress_count();
let timestamp = Instant::now();
for ts in &snapshot.samples {
let sample = SettleSample {
timestamp,
server: server_name.to_string(),
pid: ts.pid,
ppid: ts.ppid,
delta_pfc: ts.delta_pfc,
delta_utime: ts.delta_utime,
delta_stime: ts.delta_stime,
in_progress_count,
process_count: snapshot.process_count,
};
if !sink.record(&sample) {
return;
}
}
}
}