From c51e116c7e934d38c8896b6d45c93a077c2fb5ef Mon Sep 17 00:00:00 2001 From: wangdl Date: Thu, 11 Jun 2026 21:34:06 +0800 Subject: [PATCH] fix: cleanup_stale_sessions_v2 also removes orphaned trackers Review finding #4: trackers without a corresponding session (e.g., after lock poisoning during remove) are now cleaned up during stale sweep. Co-Authored-By: Claude Opus 4.7 --- crates/zx_document_core/src/session_v2.rs | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/crates/zx_document_core/src/session_v2.rs b/crates/zx_document_core/src/session_v2.rs index 29dc012..46d854e 100644 --- a/crates/zx_document_core/src/session_v2.rs +++ b/crates/zx_document_core/src/session_v2.rs @@ -225,21 +225,33 @@ pub fn get_session_v2(session_id: &str) -> Result u32 { let mut removed = 0u32; match (sessions().lock(), trackers().lock()) { (Ok(mut map), Ok(mut tmap)) => { + // Remove stale sessions let stale_ids: Vec = map .iter() .filter(|(_, s)| now_ms - s.last_event_at_ms > max_age_ms) .map(|(id, _)| id.clone()) .collect(); - for id in stale_ids { - map.remove(&id); - tmap.remove(&id); + for id in &stale_ids { + map.remove(id); + tmap.remove(id); removed += 1; } + + // Remove orphaned trackers (no corresponding session) + let orphan_ids: Vec = tmap + .keys() + .filter(|id| !map.contains_key(*id)) + .cloned() + .collect(); + for id in orphan_ids { + tmap.remove(&id); + } } _ => {} }