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 <noreply@anthropic.com>
This commit is contained in:
wangdl 2026-06-11 21:34:06 +08:00
parent 5d6bf41cab
commit 6ae4157c7c

View File

@ -225,21 +225,33 @@ pub fn get_session_v2(session_id: &str) -> Result<ReadingSessionV2, SessionError
/// Clean up stale sessions that have been inactive longer than max_age_ms.
/// This should be called on app startup to recover from crash/kill scenarios.
/// Removes both Closed and orphaned Active/Paused sessions.
/// Also removes orphaned trackers that have no corresponding session.
pub fn cleanup_stale_sessions_v2(now_ms: i64, max_age_ms: i64) -> u32 {
let mut removed = 0u32;
match (sessions().lock(), trackers().lock()) {
(Ok(mut map), Ok(mut tmap)) => {
// Remove stale sessions
let stale_ids: Vec<String> = 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<String> = tmap
.keys()
.filter(|id| !map.contains_key(*id))
.cloned()
.collect();
for id in orphan_ids {
tmap.remove(&id);
}
}
_ => {}
}