Skip to content

Commit 78c22d7

Browse files
committed
fix(sdk): RoomEventCache::event looks inside the store.
This patch fixes `RoomEventCache::event` to look inside `RoomEvents` but also inside the `EventCacheStore` to look for an event. It ultimately fallbacks to `AllEventsCache` because we can't get rid of it for the moment.
1 parent e8e8c32 commit 78c22d7

File tree

1 file changed

+62
-32
lines changed
  • crates/matrix-sdk/src/event_cache/room

1 file changed

+62
-32
lines changed

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

Lines changed: 62 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ use tokio::sync::{
3939
broadcast::{Receiver, Sender},
4040
mpsc, Notify, RwLock,
4141
};
42-
use tracing::{trace, warn};
42+
use tracing::{error, trace, warn};
4343

4444
use super::{
4545
deduplicator::DeduplicationOutcome,
@@ -182,21 +182,25 @@ impl RoomEventCache {
182182

183183
/// Try to find an event by id in this room.
184184
pub async fn event(&self, event_id: &EventId) -> Option<TimelineEvent> {
185-
if let Some((room_id, event)) =
185+
// Search in all loaded or stored events.
186+
let Ok(maybe_position_and_event) = self.inner.state.read().await.find_event(event_id).await
187+
else {
188+
error!("Failed to find the event");
189+
190+
return None;
191+
};
192+
193+
if let Some(event) = maybe_position_and_event.map(|(_position, event)| event) {
194+
Some(event)
195+
}
196+
// Search in `AllEventsCache` for known events that are not stored.
197+
else if let Some((room_id, event)) =
186198
self.inner.all_events.read().await.events.get(event_id).cloned()
187199
{
188-
if room_id == self.inner.room_id {
189-
return Some(event);
190-
}
191-
}
192-
193-
let state = self.inner.state.read().await;
194-
for (_pos, event) in state.events().revents() {
195-
if event.event_id().as_deref() == Some(event_id) {
196-
return Some(event.clone());
197-
}
200+
(room_id == self.inner.room_id).then_some(event)
201+
} else {
202+
None
198203
}
199-
None
200204
}
201205

202206
/// Try to find an event by id in this room, along with its related events.
@@ -662,7 +666,7 @@ mod private {
662666
};
663667
use matrix_sdk_common::executor::spawn;
664668
use once_cell::sync::OnceCell;
665-
use ruma::{serde::Raw, OwnedEventId, OwnedRoomId};
669+
use ruma::{serde::Raw, EventId, OwnedEventId, OwnedRoomId};
666670
use tracing::{debug, error, instrument, trace};
667671

668672
use super::{
@@ -1129,6 +1133,34 @@ mod private {
11291133
&self.events
11301134
}
11311135

1136+
/// Find a single event in this room.
1137+
///
1138+
/// It starts by looking into loaded events in `RoomEvents` before
1139+
/// looking inside the storage if it is enabled.
1140+
pub async fn find_event(
1141+
&self,
1142+
event_id: &EventId,
1143+
) -> Result<Option<(Position, TimelineEvent)>, EventCacheError> {
1144+
let room_id = self.room.as_ref();
1145+
1146+
// There are supposedly fewer events loaded in memory than in the store. Let's
1147+
// start by looking up in the `RoomEvents`.
1148+
for (position, event) in self.events().revents() {
1149+
if event.event_id().as_deref() == Some(event_id) {
1150+
return Ok(Some((position, event.clone())));
1151+
}
1152+
}
1153+
1154+
let Some(store) = self.store.get() else {
1155+
// No store, event is not present.
1156+
return Ok(None);
1157+
};
1158+
1159+
let store = store.lock().await?;
1160+
1161+
Ok(store.find_event(room_id, event_id).await?)
1162+
}
1163+
11321164
/// Gives a temporary mutable handle to the underlying in-memory events,
11331165
/// and will propagate changes to the storage once done.
11341166
///
@@ -1651,33 +1683,33 @@ mod tests {
16511683

16521684
let (items, mut stream) = room_event_cache.subscribe().await;
16531685

1654-
// The rooms knows about some cached events.
1686+
// The rooms knows about all cached events.
16551687
{
1656-
// The chunk containing this event is not loaded yet
1657-
assert!(room_event_cache.event(event_id1).await.is_none());
1658-
// The chunk containing this event **is** loaded.
1688+
assert!(room_event_cache.event(event_id1).await.is_some());
16591689
assert!(room_event_cache.event(event_id2).await.is_some());
1690+
}
16601691

1661-
// The reloaded room must contain only one event.
1692+
// But only part of events are loaded from the store
1693+
{
1694+
// The room must contain only one event because only one chunk has been loaded.
16621695
assert_eq!(items.len(), 1);
16631696
assert_eq!(items[0].event_id().unwrap(), event_id2);
16641697

16651698
assert!(stream.is_empty());
16661699
}
16671700

1668-
// Let's load more chunks to get all events.
1701+
// Let's load more chunks to load all events.
16691702
{
16701703
room_event_cache.pagination().run_backwards_once(20).await.unwrap();
16711704

16721705
assert_let_timeout!(
16731706
Ok(RoomEventCacheUpdate::UpdateTimelineEvents { diffs, .. }) = stream.recv()
16741707
);
16751708
assert_eq!(diffs.len(), 1);
1676-
assert_matches!(&diffs[0], VectorDiff::Insert { index: 0, value: _ });
1677-
1678-
// The rooms knows about more cached events.
1679-
assert!(room_event_cache.event(event_id1).await.is_some());
1680-
assert!(room_event_cache.event(event_id2).await.is_some());
1709+
assert_matches!(&diffs[0], VectorDiff::Insert { index: 0, value: event } => {
1710+
// Here you are `event_id1`!
1711+
assert_eq!(event.event_id().unwrap(), event_id1);
1712+
});
16811713

16821714
assert!(stream.is_empty());
16831715
}
@@ -1799,8 +1831,8 @@ mod tests {
17991831
assert_eq!(items[0].event_id().unwrap(), event_id2);
18001832
assert!(stream.is_empty());
18011833

1802-
// The event cache knows only one event.
1803-
assert!(room_event_cache.event(event_id1).await.is_none());
1834+
// The event cache knows only all events though, even if they aren't loaded.
1835+
assert!(room_event_cache.event(event_id1).await.is_some());
18041836
assert!(room_event_cache.event(event_id2).await.is_some());
18051837

18061838
// Let's paginate to load more events.
@@ -1810,11 +1842,9 @@ mod tests {
18101842
Ok(RoomEventCacheUpdate::UpdateTimelineEvents { diffs, .. }) = stream.recv()
18111843
);
18121844
assert_eq!(diffs.len(), 1);
1813-
assert_matches!(&diffs[0], VectorDiff::Insert { index: 0, value: _ });
1814-
1815-
// The event cache knows about the two events now!
1816-
assert!(room_event_cache.event(event_id1).await.is_some());
1817-
assert!(room_event_cache.event(event_id2).await.is_some());
1845+
assert_matches!(&diffs[0], VectorDiff::Insert { index: 0, value: event } => {
1846+
assert_eq!(event.event_id().unwrap(), event_id1);
1847+
});
18181848

18191849
assert!(stream.is_empty());
18201850

0 commit comments

Comments
 (0)