mirror of
https://github.com/matrix-org/matrix-rust-sdk.git
synced 2026-08-02 10:57:33 -04:00
refactor(sdk): R2D2 replaces UTD on PinnedEventsCache without involving RoomEventCache.
This patch updates R2D2 to fetch the `PinnedEventsCache` from `EventCache` without using `RoomEventCache`.
This commit is contained in:
@@ -201,6 +201,16 @@ impl Caches {
|
||||
})
|
||||
}
|
||||
|
||||
/// Get a [`PinnedEventsCache`] if it has been initialised.
|
||||
///
|
||||
/// [`PinnedEventsCache`]: pinned_events::PinnedEventsCache
|
||||
#[cfg(feature = "e2e-encryption")]
|
||||
pub(super) fn pinned_events_without_initialisation(
|
||||
&self,
|
||||
) -> Option<&pinned_events::PinnedEventsCache> {
|
||||
self.pinned_events.get()
|
||||
}
|
||||
|
||||
/// Update all the event caches with a [`JoinedRoomUpdate`].
|
||||
pub(super) async fn handle_joined_room_update(&self, updates: JoinedRoomUpdate) -> Result<()> {
|
||||
let Self { room, threads, pinned_events, internals } = &self;
|
||||
|
||||
@@ -530,7 +530,7 @@ impl PinnedEventsCache {
|
||||
/// list of decrypted events, and replace them, while alerting observers
|
||||
/// about the update.
|
||||
#[cfg(feature = "e2e-encryption")]
|
||||
pub(in crate::event_cache) async fn replace_utds(&self, events: &[ResolvedUtd]) -> Result<()> {
|
||||
pub(in super::super) async fn replace_utds(&self, events: &[ResolvedUtd]) -> Result<()> {
|
||||
let mut guard = self.inner.state.write().await?;
|
||||
|
||||
if guard.state.chunk.replace_utds(events) {
|
||||
|
||||
@@ -402,6 +402,19 @@ impl EventCache {
|
||||
|
||||
Ok((caches_for_room.pinned_events()?.clone(), drop_handles))
|
||||
}
|
||||
|
||||
/// Return a pinned-events-specific view over the [`EventCache`] if it has
|
||||
/// been initialised.
|
||||
#[cfg(feature = "e2e-encryption")]
|
||||
async fn pinned_events_without_initialisation(
|
||||
&self,
|
||||
room_id: &RoomId,
|
||||
) -> Result<Option<PinnedEventsCache>> {
|
||||
let caches_for_room = self.inner.all_caches_for_room(room_id).await?;
|
||||
|
||||
Ok(caches_for_room.pinned_events_without_initialisation().cloned())
|
||||
}
|
||||
|
||||
/// Cleanly clear all the rooms' event caches.
|
||||
///
|
||||
/// This will notify any live observers that the room has been cleared.
|
||||
|
||||
@@ -370,14 +370,14 @@ impl EventCache {
|
||||
|
||||
// Phase 1: under the room state write lock, collect cache handles and
|
||||
// perform all room-linked-chunk mutations. We deliberately do NOT call
|
||||
// replace_utds() on event-focused/pinned caches here to avoid an ABBA deadlock:
|
||||
// pagination holds an event-focused cache lock and then tries to acquire the
|
||||
// room state lock (via `save_events`), while this method would hold the
|
||||
// room state lock and try to acquire event-focused cache locks.
|
||||
let (pinned_cache, ef_caches) = {
|
||||
// replace_utds() on event-focused/pinned-evenst caches here to avoid an ABBA
|
||||
// deadlock: pagination holds an event-focused cache lock and then tries
|
||||
// to acquire the room state lock (via `save_events`), while this method
|
||||
// would hold the room state lock and try to acquire event-focused cache
|
||||
// locks.
|
||||
let ef_caches = {
|
||||
let mut state = room_cache.state().write().await?;
|
||||
|
||||
let pinned_cache = state.pinned_events_cache().cloned();
|
||||
let ef_caches: Vec<_> = state.event_focused_caches().cloned().collect();
|
||||
|
||||
// Consider the room linked chunk.
|
||||
@@ -416,15 +416,17 @@ impl EventCache {
|
||||
Some(RoomEventCacheGenericUpdate { room_id: room_id.to_owned() }),
|
||||
);
|
||||
|
||||
(pinned_cache, ef_caches)
|
||||
ef_caches
|
||||
};
|
||||
// Room state write lock is dropped here.
|
||||
|
||||
// Phase 2: replace UTDs in pinned and event-focused caches WITHOUT
|
||||
// holding the room state lock. These caches have their own internal
|
||||
// locks and don't need the room state lock.
|
||||
if let Some(pinned_cache) = pinned_cache {
|
||||
pinned_cache.replace_utds(&events).await?;
|
||||
// Phase 2: replace UTDs in pinned-events and event-focused caches
|
||||
// WITHOUT holding the room state lock. These caches have their own
|
||||
// internal locks and don't need the room state lock.
|
||||
if let Ok(Some(pinned_events_cache)) =
|
||||
self.pinned_events_without_initialisation(room_id).await
|
||||
{
|
||||
pinned_events_cache.replace_utds(&events).await?;
|
||||
}
|
||||
|
||||
// TODO: This ain't great for performance; there shouldn't be that many
|
||||
|
||||
Reference in New Issue
Block a user