From 4e6d95f87f29e08bc32f05ee6f2c29220265d397 Mon Sep 17 00:00:00 2001 From: Cylae <13425054+Cylae@users.noreply.github.com> Date: Wed, 9 Sep 2026 01:08:18 +0000 Subject: [PATCH] =?UTF-8?q?=E2=9A=A1=20Cache=20hardware=20detection=20and?= =?UTF-8?q?=20optimize=20virtual=20filesystem=20filtering?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Cache HardwareInfo::detect result using std::sync::OnceLock to avoid repeated expensive system information detection calls. Optimize virtual filesystem filtering in disk summation loop using byte slice matching. --- server_manager/benches/service_benchmark.rs | 12 ++++++- server_manager/src/core/hardware.rs | 37 +++++++++++++++------ 2 files changed, 38 insertions(+), 11 deletions(-) diff --git a/server_manager/benches/service_benchmark.rs b/server_manager/benches/service_benchmark.rs index 46a961c..b5571f8 100644 --- a/server_manager/benches/service_benchmark.rs +++ b/server_manager/benches/service_benchmark.rs @@ -107,11 +107,21 @@ fn benchmark_port_matrix_generation(c: &mut Criterion) { }); } +fn benchmark_hardware_detection(c: &mut Criterion) { + c.bench_function("hardware_detection", |b| { + b.iter(|| { + let hw = HardwareInfo::detect(); + criterion::black_box(hw); + }) + }); +} + criterion_group!( benches, benchmark_catalog_retrieval, benchmark_compose_generation, benchmark_validation_throughput, - benchmark_port_matrix_generation + benchmark_port_matrix_generation, + benchmark_hardware_detection ); criterion_main!(benches); diff --git a/server_manager/src/core/hardware.rs b/server_manager/src/core/hardware.rs index e711462..94acbbd 100644 --- a/server_manager/src/core/hardware.rs +++ b/server_manager/src/core/hardware.rs @@ -1,9 +1,12 @@ use log::{info, warn}; use nix::unistd::User; use std::path::Path; +use std::sync::OnceLock; use sysinfo::{DiskExt, System, SystemExt}; use which::which; +static HARDWARE_CACHE: OnceLock = OnceLock::new(); + #[derive(Debug, Clone, Copy, PartialEq)] pub enum HardwareProfile { Low, // < 4GB RAM, <= 2 cores @@ -26,6 +29,10 @@ pub struct HardwareInfo { impl HardwareInfo { pub fn detect() -> Self { + HARDWARE_CACHE.get_or_init(Self::detect_uncached).clone() + } + + pub fn detect_uncached() -> Self { let (user_id, group_id) = Self::detect_user(); let mut sys = System::new(); sys.refresh_memory(); @@ -41,16 +48,17 @@ impl HardwareInfo { let cpu_cores = sys.cpus().len(); - let mut disk_gb = 0; - for disk in sys.disks() { - // Filter out virtual filesystems to prevent double counting (e.g., overlayfs) - let fs_type = std::str::from_utf8(disk.file_system()).unwrap_or("unknown"); - match fs_type { - "overlay" | "tmpfs" | "devtmpfs" | "squashfs" | "sysfs" | "proc" => continue, - _ => {} - } - disk_gb += disk.total_space() / 1024 / 1024 / 1024; - } + let disk_gb = sys + .disks() + .iter() + .filter(|disk| { + !matches!( + disk.file_system(), + b"overlay" | b"tmpfs" | b"devtmpfs" | b"squashfs" | b"sysfs" | b"proc" + ) + }) + .map(|disk| disk.total_space() / 1024 / 1024 / 1024) + .sum(); let profile = Self::evaluate_profile(ram_gb, cpu_cores, swap_gb); @@ -158,4 +166,13 @@ mod tests { HardwareProfile::Standard ); // 6GB RAM + Swap -> Standard } + + #[test] + fn test_hardware_info_cached_and_uncached_detection() { + let hw_uncached = HardwareInfo::detect_uncached(); + let hw_cached = HardwareInfo::detect(); + assert_eq!(hw_uncached.cpu_cores, hw_cached.cpu_cores); + assert_eq!(hw_uncached.ram_gb, hw_cached.ram_gb); + assert_eq!(hw_uncached.profile, hw_cached.profile); + } }