fix for macos defect where processes less than .01% were being filtered

This commit is contained in:
jasonwitty 2025-08-27 16:55:09 -07:00
parent 2fe005ed90
commit f0858525e8
4 changed files with 51 additions and 30 deletions

2
Cargo.lock generated
View File

@ -2187,7 +2187,7 @@ dependencies = [
[[package]] [[package]]
name = "socktop_agent" name = "socktop_agent"
version = "1.40.62" version = "1.40.63"
dependencies = [ dependencies = [
"anyhow", "anyhow",
"assert_cmd", "assert_cmd",

View File

@ -1,6 +1,6 @@
[package] [package]
name = "socktop_agent" name = "socktop_agent"
version = "1.40.62" version = "1.40.63"
authors = ["Jason Witty <jasonpwitty+socktop@proton.me>"] authors = ["Jason Witty <jasonpwitty+socktop@proton.me>"]
description = "Remote system monitor over WebSocket, TUI like top" description = "Remote system monitor over WebSocket, TUI like top"
edition = "2021" edition = "2021"

View File

@ -441,28 +441,38 @@ pub async fn collect_processes_all(state: &AppState) -> ProcessesPayload {
} }
} }
// Single efficient refresh: only update processes using significant CPU // Single efficient refresh with optimized CPU collection
let (total_count, procs) = { let (total_count, procs) = {
let mut sys = state.sys.lock().await; let mut sys = state.sys.lock().await;
let kind = ProcessRefreshKind::nothing().with_memory();
// Only do a deep refresh if system load is significant // Optimize refresh strategy based on system load
if load > 5.0 { if load > 5.0 {
let kind = ProcessRefreshKind::nothing().with_cpu().with_memory(); // For active systems, get accurate CPU metrics
sys.refresh_processes_specifics(ProcessesToUpdate::All, false, kind); sys.refresh_processes_specifics(
} ProcessesToUpdate::All,
false,
kind.with_cpu(),
);
} else {
// For idle systems, just get basic process info
sys.refresh_processes_specifics(
ProcessesToUpdate::All,
false,
kind,
);
sys.refresh_cpu_usage(); sys.refresh_cpu_usage();
}
let total_count = sys.processes().len(); let total_count = sys.processes().len();
let cpu_count = sys.cpus().len() as f32;
// Reuse allocations via process cache // Reuse allocations via process cache
let mut proc_cache = state.proc_cache.lock().await; let mut proc_cache = state.proc_cache.lock().await;
proc_cache.reusable_vec.clear(); proc_cache.reusable_vec.clear();
// Filter and collect processes with meaningful CPU usage // Collect all processes, will sort by CPU later
for p in sys.processes().values() { for p in sys.processes().values() {
let raw = p.cpu_usage();
if raw > cpu_threshold {
// Skip negligible CPU users
let pid = p.pid().as_u32(); let pid = p.pid().as_u32();
// Reuse cached name if available // Reuse cached name if available
@ -474,20 +484,30 @@ pub async fn collect_processes_all(state: &AppState) -> ProcessesPayload {
new_name new_name
}; };
// Normalize CPU by core count (like Linux implementation)
let raw = p.cpu_usage();
let normalized_cpu = (raw / cpu_count).clamp(0.0, 100.0);
proc_cache.reusable_vec.push(ProcessInfo { proc_cache.reusable_vec.push(ProcessInfo {
pid, pid,
name, name,
cpu_usage: raw.clamp(0.0, 100.0), cpu_usage: normalized_cpu,
mem_bytes: p.memory(), mem_bytes: p.memory(),
}); });
} }
}
// Sort by CPU usage
proc_cache.reusable_vec.sort_by(|a, b| {
b.cpu_usage
.partial_cmp(&a.cpu_usage)
.unwrap_or(std::cmp::Ordering::Equal)
});
// Clean up old process names cache when it grows too large // Clean up old process names cache when it grows too large
let cache_cleanup_threshold = std::env::var("SOCKTOP_AGENT_NAME_CACHE_CLEANUP_THRESHOLD") let cache_cleanup_threshold = std::env::var("SOCKTOP_AGENT_NAME_CACHE_CLEANUP_THRESHOLD")
.ok() .ok()
.and_then(|v| v.parse().ok()) .and_then(|v| v.parse().ok())
.unwrap_or(100); // Default cleanup threshold .unwrap_or(1000); // Default: most modern systems have 400-700 processes
if total_count > proc_cache.names.len() + cache_cleanup_threshold { if total_count > proc_cache.names.len() + cache_cleanup_threshold {
let now = std::time::Instant::now(); let now = std::time::Instant::now();
@ -501,6 +521,7 @@ pub async fn collect_processes_all(state: &AppState) -> ProcessesPayload {
); );
} }
// Get all processes, but keep the original ordering by CPU usage
(total_count, proc_cache.reusable_vec.clone()) (total_count, proc_cache.reusable_vec.clone())
}; };

View File

@ -29,8 +29,8 @@ pub struct ProcessCache {
impl Default for ProcessCache { impl Default for ProcessCache {
fn default() -> Self { fn default() -> Self {
Self { Self {
names: HashMap::with_capacity(256), names: HashMap::with_capacity(1000), // Pre-allocate for typical modern system process count
reusable_vec: Vec::with_capacity(256), reusable_vec: Vec::with_capacity(1000),
} }
} }
} }