Skip to content

Commit d317e5d

Browse files
committed
feat(event cache): don't react specifically to limited timelines, when storage's enabled
1 parent ee93c27 commit d317e5d

File tree

3 files changed

+104
-14
lines changed

3 files changed

+104
-14
lines changed

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

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -313,7 +313,7 @@ impl EventCache {
313313
prev_batch: Option<String>,
314314
) -> Result<()> {
315315
// If the event cache's storage has been enabled, do nothing.
316-
if self.inner.store.get().is_some() {
316+
if self.inner.has_storage() {
317317
return Ok(());
318318
}
319319

@@ -387,6 +387,11 @@ impl EventCacheInner {
387387
self.client.get().ok_or(EventCacheError::ClientDropped)
388388
}
389389

390+
/// Has persistent storage been enabled for the event cache?
391+
fn has_storage(&self) -> bool {
392+
self.store.get().is_some()
393+
}
394+
390395
/// Clears all the room's data.
391396
async fn clear_all_rooms(&self) -> Result<()> {
392397
// Note: one must NOT clear the `by_room` map, because if something subscribed
@@ -419,7 +424,9 @@ impl EventCacheInner {
419424
for (room_id, left_room_update) in updates.leave {
420425
let room = self.for_room(&room_id).await?;
421426

422-
if let Err(err) = room.inner.handle_left_room_update(left_room_update).await {
427+
if let Err(err) =
428+
room.inner.handle_left_room_update(self.has_storage(), left_room_update).await
429+
{
423430
// Non-fatal error, try to continue to the next room.
424431
error!("handling left room update: {err}");
425432
}
@@ -429,7 +436,9 @@ impl EventCacheInner {
429436
for (room_id, joined_room_update) in updates.join {
430437
let room = self.for_room(&room_id).await?;
431438

432-
if let Err(err) = room.inner.handle_joined_room_update(joined_room_update).await {
439+
if let Err(err) =
440+
room.inner.handle_joined_room_update(self.has_storage(), joined_room_update).await
441+
{
433442
// Non-fatal error, try to continue to the next room.
434443
error!("handling joined room update: {err}");
435444
}
@@ -604,7 +613,10 @@ mod tests {
604613

605614
room_event_cache
606615
.inner
607-
.handle_joined_room_update(JoinedRoomUpdate { account_data, ..Default::default() })
616+
.handle_joined_room_update(
617+
event_cache.inner.has_storage(),
618+
JoinedRoomUpdate { account_data, ..Default::default() },
619+
)
608620
.await
609621
.unwrap();
610622

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

Lines changed: 18 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -286,8 +286,13 @@ impl RoomEventCacheInner {
286286
}
287287
}
288288

289-
pub(super) async fn handle_joined_room_update(&self, updates: JoinedRoomUpdate) -> Result<()> {
289+
pub(super) async fn handle_joined_room_update(
290+
&self,
291+
has_storage: bool,
292+
updates: JoinedRoomUpdate,
293+
) -> Result<()> {
290294
self.handle_timeline(
295+
has_storage,
291296
updates.timeline,
292297
updates.ephemeral.clone(),
293298
updates.ambiguity_changes,
@@ -301,11 +306,12 @@ impl RoomEventCacheInner {
301306

302307
async fn handle_timeline(
303308
&self,
309+
has_storage: bool,
304310
timeline: Timeline,
305311
ephemeral_events: Vec<Raw<AnySyncEphemeralRoomEvent>>,
306312
ambiguity_changes: BTreeMap<OwnedEventId, AmbiguityChange>,
307313
) -> Result<()> {
308-
if timeline.limited {
314+
if !has_storage && timeline.limited {
309315
// Ideally we'd try to reconcile existing events against those received in the
310316
// timeline, but we're not there yet. In the meanwhile, clear the
311317
// items from the room. TODO: implement Smart Matching™.
@@ -334,8 +340,13 @@ impl RoomEventCacheInner {
334340
Ok(())
335341
}
336342

337-
pub(super) async fn handle_left_room_update(&self, updates: LeftRoomUpdate) -> Result<()> {
338-
self.handle_timeline(updates.timeline, Vec::new(), updates.ambiguity_changes).await?;
343+
pub(super) async fn handle_left_room_update(
344+
&self,
345+
has_storage: bool,
346+
updates: LeftRoomUpdate,
347+
) -> Result<()> {
348+
self.handle_timeline(has_storage, updates.timeline, Vec::new(), updates.ambiguity_changes)
349+
.await?;
339350
Ok(())
340351
}
341352

@@ -990,7 +1001,7 @@ mod tests {
9901001

9911002
room_event_cache
9921003
.inner
993-
.handle_joined_room_update(JoinedRoomUpdate { timeline, ..Default::default() })
1004+
.handle_joined_room_update(true, JoinedRoomUpdate { timeline, ..Default::default() })
9941005
.await
9951006
.unwrap();
9961007

@@ -1060,7 +1071,7 @@ mod tests {
10601071

10611072
room_event_cache
10621073
.inner
1063-
.handle_joined_room_update(JoinedRoomUpdate { timeline, ..Default::default() })
1074+
.handle_joined_room_update(true, JoinedRoomUpdate { timeline, ..Default::default() })
10641075
.await
10651076
.unwrap();
10661077

@@ -1188,7 +1199,7 @@ mod tests {
11881199
let timeline = Timeline { limited: false, prev_batch: None, events: vec![ev1] };
11891200
room_event_cache
11901201
.inner
1191-
.handle_joined_room_update(JoinedRoomUpdate { timeline, ..Default::default() })
1202+
.handle_joined_room_update(true, JoinedRoomUpdate { timeline, ..Default::default() })
11921203
.await
11931204
.unwrap();
11941205

crates/matrix-sdk/tests/integration/event_cache.rs

Lines changed: 70 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,11 @@
11
use std::{future::ready, ops::ControlFlow, time::Duration};
22

3-
use assert_matches2::{assert_let, assert_matches};
3+
use assert_matches::assert_matches;
4+
use assert_matches2::assert_let;
45
use matrix_sdk::{
56
event_cache::{
6-
paginator::PaginatorState, BackPaginationOutcome, EventCacheError, RoomEventCacheUpdate,
7-
TimelineHasBeenResetWhilePaginating,
7+
paginator::PaginatorState, BackPaginationOutcome, EventCacheError, EventsOrigin,
8+
RoomEventCacheUpdate, TimelineHasBeenResetWhilePaginating,
89
},
910
test_utils::{assert_event_matches_msg, logged_in_client_with_server, mocks::MatrixMockServer},
1011
};
@@ -852,3 +853,69 @@ async fn test_limited_timeline_resets_pagination() {
852853

853854
assert!(room_stream.is_empty());
854855
}
856+
857+
#[async_test]
858+
async fn test_limited_timeline_with_storage() {
859+
let server = MatrixMockServer::new().await;
860+
let client = server.client_builder().build().await;
861+
862+
let event_cache = client.event_cache();
863+
864+
// Don't forget to subscribe and like^W enable storage!
865+
event_cache.subscribe().unwrap();
866+
event_cache.enable_storage().unwrap();
867+
868+
let room_id = room_id!("!galette:saucisse.bzh");
869+
let room = server.sync_joined_room(&client, room_id).await;
870+
871+
let (room_event_cache, _drop_handles) = room.event_cache().await.unwrap();
872+
873+
let f = EventFactory::new().room(room_id).sender(user_id!("@ben:saucisse.bzh"));
874+
875+
// First sync: get a message.
876+
server
877+
.sync_room(
878+
&client,
879+
JoinedRoomBuilder::new(room_id).add_timeline_event(f.text_msg("hey yo")),
880+
)
881+
.await;
882+
883+
let (initial_events, mut subscriber) = room_event_cache.subscribe().await.unwrap();
884+
885+
// This is racy: either the sync has been handled, or it hasn't yet.
886+
if initial_events.is_empty() {
887+
assert_let_timeout!(
888+
Ok(RoomEventCacheUpdate::AddTimelineEvents { events, .. }) = subscriber.recv()
889+
);
890+
assert_eq!(events.len(), 1);
891+
assert_event_matches_msg(&events[0], "hey yo");
892+
} else {
893+
assert_eq!(initial_events.len(), 1);
894+
assert_event_matches_msg(&initial_events[0], "hey yo");
895+
}
896+
897+
assert!(subscriber.is_empty());
898+
899+
// Second update: get a message but from a limited timeline.
900+
server
901+
.sync_room(
902+
&client,
903+
JoinedRoomBuilder::new(room_id)
904+
.add_timeline_event(f.text_msg("gappy!"))
905+
.set_timeline_limited(),
906+
)
907+
.await;
908+
909+
let update = timeout(Duration::from_secs(2), subscriber.recv())
910+
.await
911+
.expect("timeout after receiving a sync update")
912+
.expect("should've received a room event cache update");
913+
914+
assert_matches!(update, RoomEventCacheUpdate::AddTimelineEvents { events, origin: EventsOrigin::Sync } => {
915+
assert_eq!(events.len(), 1);
916+
assert_event_matches_msg(&events[0], "gappy!");
917+
});
918+
919+
// That's all, folks!
920+
assert!(subscriber.is_empty());
921+
}

0 commit comments

Comments
 (0)