From 8ec23a95d55e095097547fcecdc517ee30e54cf9 Mon Sep 17 00:00:00 2001 From: Benjamin Bouvier Date: Wed, 20 Aug 2025 14:37:16 +0200 Subject: [PATCH] fix(event cache): avoid cycle of `EventCacheInner` with the `auto_shrink_linked_chunk_task` The task would stop when the receiver is closed; for the receiver to be closed, the sender ought to be closed too. Because the sender lives in `EventCacheInner`, and the task would hold onto an `EventCacheInner` struct, the sender would never be dropped, so the full `EventCacheInner` would leak, as a result. --- crates/matrix-sdk/src/event_cache/mod.rs | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/crates/matrix-sdk/src/event_cache/mod.rs b/crates/matrix-sdk/src/event_cache/mod.rs index 45225d62c..411f145e1 100644 --- a/crates/matrix-sdk/src/event_cache/mod.rs +++ b/crates/matrix-sdk/src/event_cache/mod.rs @@ -30,7 +30,7 @@ use std::{ collections::{BTreeMap, HashMap}, fmt, - sync::{Arc, OnceLock}, + sync::{Arc, OnceLock, Weak}, }; use eyeball::{SharedObservable, Subscriber}; @@ -250,7 +250,7 @@ impl EventCache { self.inner.auto_shrink_sender.get_or_init(|| auto_shrink_sender); let auto_shrink_linked_chunk_task = spawn(Self::auto_shrink_linked_chunk_task( - self.inner.clone(), + Arc::downgrade(&self.inner), auto_shrink_receiver, )); @@ -352,12 +352,16 @@ impl EventCache { /// time to do so (new subscribers might have spawned in the meanwhile). #[instrument(skip_all)] async fn auto_shrink_linked_chunk_task( - inner: Arc, + inner: Weak, mut rx: mpsc::Receiver, ) { while let Some(room_id) = rx.recv().await { trace!(for_room = %room_id, "received notification to shrink"); + let Some(inner) = inner.upgrade() else { + return; + }; + let room = match inner.for_room(&room_id).await { Ok(room) => room, Err(err) => { @@ -397,6 +401,8 @@ impl EventCache { } } } + + info!("Auto-shrink linked chunk task has been closed, exiting"); } /// Return a room-specific view over the [`EventCache`].