Skip to content

Commit 0ddb63e

Browse files
committed
refactor(sdk): R2D2 replaces UTD on PinnedEventsCache without involving RoomEventCache.
This patch updates R2D2 to fetch the `PinnedEventsCache` from `EventCache` without using `RoomEventCache`.
1 parent 29b1a59 commit 0ddb63e

4 files changed

Lines changed: 37 additions & 13 deletions

File tree

crates/matrix-sdk/src/event_cache/caches/mod.rs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -201,6 +201,15 @@ impl Caches {
201201
})
202202
}
203203

204+
/// Get a [`PinnedEventsCache`] if it has been initialised.
205+
///
206+
/// [`PinnedEventsCache`]: pinned_events::PinnedEventsCache
207+
pub(super) fn pinned_events_without_initialisation(
208+
&self,
209+
) -> Option<&pinned_events::PinnedEventsCache> {
210+
self.pinned_events.get()
211+
}
212+
204213
/// Update all the event caches with a [`JoinedRoomUpdate`].
205214
pub(super) async fn handle_joined_room_update(&self, updates: JoinedRoomUpdate) -> Result<()> {
206215
let Self { room, threads, pinned_events, internals } = &self;

crates/matrix-sdk/src/event_cache/caches/pinned_events/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -530,7 +530,7 @@ impl PinnedEventsCache {
530530
/// list of decrypted events, and replace them, while alerting observers
531531
/// about the update.
532532
#[cfg(feature = "e2e-encryption")]
533-
pub(in crate::event_cache) async fn replace_utds(&self, events: &[ResolvedUtd]) -> Result<()> {
533+
pub(in super::super) async fn replace_utds(&self, events: &[ResolvedUtd]) -> Result<()> {
534534
let mut guard = self.inner.state.write().await?;
535535

536536
if guard.state.chunk.replace_utds(events) {

crates/matrix-sdk/src/event_cache/mod.rs

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -402,6 +402,19 @@ impl EventCache {
402402

403403
Ok((caches_for_room.pinned_events()?.clone(), drop_handles))
404404
}
405+
406+
/// Return a pinned-events-specific view over the [`EventCache`] if it has
407+
/// been initialised.
408+
#[cfg(feature = "e2e-encryption")]
409+
async fn pinned_events_without_initialisation(
410+
&self,
411+
room_id: &RoomId,
412+
) -> Result<Option<PinnedEventsCache>> {
413+
let caches_for_room = self.inner.all_caches_for_room(room_id).await?;
414+
415+
Ok(caches_for_room.pinned_events_without_initialisation().cloned())
416+
}
417+
405418
/// Cleanly clear all the rooms' event caches.
406419
///
407420
/// This will notify any live observers that the room has been cleared.

crates/matrix-sdk/src/event_cache/redecryptor.rs

Lines changed: 14 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -370,14 +370,14 @@ impl EventCache {
370370

371371
// Phase 1: under the room state write lock, collect cache handles and
372372
// perform all room-linked-chunk mutations. We deliberately do NOT call
373-
// replace_utds() on event-focused/pinned caches here to avoid an ABBA deadlock:
374-
// pagination holds an event-focused cache lock and then tries to acquire the
375-
// room state lock (via `save_events`), while this method would hold the
376-
// room state lock and try to acquire event-focused cache locks.
377-
let (pinned_cache, ef_caches) = {
373+
// replace_utds() on event-focused/pinned-evenst caches here to avoid an ABBA
374+
// deadlock: pagination holds an event-focused cache lock and then tries
375+
// to acquire the room state lock (via `save_events`), while this method
376+
// would hold the room state lock and try to acquire event-focused cache
377+
// locks.
378+
let ef_caches = {
378379
let mut state = room_cache.state().write().await?;
379380

380-
let pinned_cache = state.pinned_events_cache().cloned();
381381
let ef_caches: Vec<_> = state.event_focused_caches().cloned().collect();
382382

383383
// Consider the room linked chunk.
@@ -416,15 +416,17 @@ impl EventCache {
416416
Some(RoomEventCacheGenericUpdate { room_id: room_id.to_owned() }),
417417
);
418418

419-
(pinned_cache, ef_caches)
419+
ef_caches
420420
};
421421
// Room state write lock is dropped here.
422422

423-
// Phase 2: replace UTDs in pinned and event-focused caches WITHOUT
424-
// holding the room state lock. These caches have their own internal
425-
// locks and don't need the room state lock.
426-
if let Some(pinned_cache) = pinned_cache {
427-
pinned_cache.replace_utds(&events).await?;
423+
// Phase 2: replace UTDs in pinned-events and event-focused caches
424+
// WITHOUT holding the room state lock. These caches have their own
425+
// internal locks and don't need the room state lock.
426+
if let Ok(Some(pinned_events_cache)) =
427+
self.pinned_events_without_initialisation(room_id).await
428+
{
429+
pinned_events_cache.replace_utds(&events).await?;
428430
}
429431

430432
// TODO: This ain't great for performance; there shouldn't be that many

0 commit comments

Comments
 (0)