Skip to content

Commit daff99c

Browse files
committed
feat(event cache): shrink the linked chunk upon gappy syncs
1 parent 337a84e commit daff99c

File tree

1 file changed

+36
-2
lines changed
  • crates/matrix-sdk/src/event_cache/room

1 file changed

+36
-2
lines changed

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

Lines changed: 36 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -435,7 +435,7 @@ impl RoomEventCacheInner {
435435
} else {
436436
// Add the previous back-pagination token (if present), followed by the timeline
437437
// events themselves.
438-
let (_, sync_timeline_events_diffs) = state
438+
let ((), mut sync_timeline_events_diffs) = state
439439
.with_events_mut(|room_events| {
440440
// If we only received duplicated events, we don't need to store the gap: if
441441
// there was a gap, we'd have received an unknown event at the tail of
@@ -461,8 +461,20 @@ impl RoomEventCacheInner {
461461
})
462462
.await?;
463463

464+
if prev_batch.is_some() && !all_duplicates {
464465
// If there was a previous batch token, and there's at least one non-duplicated
466+
// new event, unload the chunks so it only contains the last
467+
// one; otherwise, there might be a valid gap in between, and
468+
// observers may not render it (yet). In this case, override the
469+
// updates with those from the unload.
470+
//
465471
// We must do this *after* the above call to `.with_events_mut`, so the new
472+
// events and gaps are properly persisted to storage.
473+
if let Some(new_events_diffs) = state.shrink_to_last_chunk().await? {
474+
sync_timeline_events_diffs = new_events_diffs;
475+
}
476+
}
477+
466478
{
467479
// Fill the AllEventsCache.
468480
let mut all_events = self.all_events.write().await;
@@ -1687,6 +1699,8 @@ mod tests {
16871699
#[cfg(not(target_arch = "wasm32"))] // This uses the cross-process lock, so needs time support.
16881700
#[async_test]
16891701
async fn test_no_useless_gaps() {
1702+
use crate::event_cache::room::LoadMoreEventsBackwardsOutcome;
1703+
16901704
let room_id = room_id!("!galette:saucisse.bzh");
16911705

16921706
let client = MockClientBuilder::new("http://localhost".to_owned()).build().await;
@@ -1722,7 +1736,7 @@ mod tests {
17221736
.unwrap();
17231737

17241738
{
1725-
let state = room_event_cache.inner.state.read().await;
1739+
let mut state = room_event_cache.inner.state.write().await;
17261740

17271741
let mut num_gaps = 0;
17281742
let mut num_events = 0;
@@ -1734,6 +1748,26 @@ mod tests {
17341748
}
17351749
}
17361750

1751+
// The limited sync unloads the chunk, so it will appear as if there are only
1752+
// the events.
1753+
assert_eq!(num_gaps, 0);
1754+
assert_eq!(num_events, 1);
1755+
1756+
// But if I manually reload more of the chunk, the gap will be present.
1757+
assert_matches!(
1758+
state.load_more_events_backwards().await.unwrap(),
1759+
LoadMoreEventsBackwardsOutcome::Gap
1760+
);
1761+
1762+
num_gaps = 0;
1763+
num_events = 0;
1764+
for c in state.events().chunks() {
1765+
match c.content() {
1766+
ChunkContent::Items(items) => num_events += items.len(),
1767+
ChunkContent::Gap(_) => num_gaps += 1,
1768+
}
1769+
}
1770+
17371771
// The gap must have been stored.
17381772
assert_eq!(num_gaps, 1);
17391773
assert_eq!(num_events, 1);

0 commit comments

Comments
 (0)