Fix data duplication in cached collector architecture

Critical bug fix: Collectors were appending to Vecs instead of replacing them,
causing duplicate entries with each collection cycle.

Fixed by adding .clear() calls before populating:
- Memory collector: tmpfs Vec (was showing 11+ duplicates)
- Disk collector: drives and pools Vecs
- Systemd collector: services Vec
- Network collector: Already correct (assigns new Vec)

This prevents the exponential growth of duplicate entries in the dashboard UI.
This commit is contained in:
Christoffer Martinsson 2025-11-27 22:45:44 +01:00
parent 2740de9b54
commit 14618c59c6
3 changed files with 13 additions and 1 deletions

View File

@ -530,6 +530,9 @@ impl DiskCollector {
/// Populate drives data into AgentData
fn populate_drives_data(&self, physical_drives: &[PhysicalDrive], smart_data: &HashMap<String, SmartData>, agent_data: &mut AgentData) -> Result<(), CollectorError> {
// Clear existing drives data to prevent duplicates in cached architecture
agent_data.system.storage.drives.clear();
for drive in physical_drives {
let smart = smart_data.get(&drive.name);
@ -567,6 +570,9 @@ impl DiskCollector {
/// Populate pools data into AgentData
fn populate_pools_data(&self, mergerfs_pools: &[MergerfsPool], smart_data: &HashMap<String, SmartData>, agent_data: &mut AgentData) -> Result<(), CollectorError> {
// Clear existing pools data to prevent duplicates in cached architecture
agent_data.system.storage.pools.clear();
for pool in mergerfs_pools {
// Calculate pool health and statuses based on member drive health
let (pool_health, health_status, usage_status, data_drive_data, parity_drive_data) = self.calculate_pool_health(pool, smart_data);

View File

@ -97,6 +97,9 @@ impl MemoryCollector {
/// Populate tmpfs data into AgentData
async fn populate_tmpfs_data(&self, agent_data: &mut AgentData) -> Result<(), CollectorError> {
// Clear existing tmpfs data to prevent duplicates in cached architecture
agent_data.system.memory.tmpfs.clear();
// Discover all tmpfs mount points
let tmpfs_mounts = self.discover_tmpfs_mounts()?;

View File

@ -915,6 +915,9 @@ impl SystemdCollector {
#[async_trait]
impl Collector for SystemdCollector {
async fn collect_structured(&self, agent_data: &mut AgentData) -> Result<(), CollectorError> {
// Clear existing services data to prevent duplicates in cached architecture
agent_data.services.clear();
// Use cached complete data if available and fresh
if let Some(cached_complete_services) = self.get_cached_complete_services() {
for service_data in cached_complete_services {