Skip to content

Commit 187b646

Browse files
committed
refactor(event cache): have the room pagination handle waiting for the previous pagination token from sync
This case is very specific to the room pagination, and will not apply to the thread pagination; by removing it from the generic pagination logic, we'll be able to use the generic pagination logic for threads.
1 parent 8a47e3c commit 187b646

File tree

2 files changed

+37
-48
lines changed

2 files changed

+37
-48
lines changed

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

Lines changed: 32 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -185,35 +185,39 @@ impl RoomPagination {
185185
let mut state_guard = self.inner.state.write().await;
186186

187187
match state_guard.load_more_events_backwards().await? {
188-
LoadMoreEventsBackwardsOutcome::WaitForInitialPrevToken => {
189-
const DEFAULT_WAIT_FOR_TOKEN_DURATION: Duration = Duration::from_secs(3);
190-
191-
// Release the state guard while waiting, to not deadlock the sync task.
192-
drop(state_guard);
193-
194-
// Otherwise, wait for a notification that we received a previous-batch token.
195-
trace!("waiting for a pagination token…");
196-
let _ = timeout(
197-
self.inner.pagination_batch_token_notifier.notified(),
198-
DEFAULT_WAIT_FOR_TOKEN_DURATION,
199-
)
200-
.await;
201-
trace!("done waiting");
202-
203-
self.inner.state.write().await.waited_for_initial_prev_token = true;
204-
205-
// Retry!
206-
//
207-
// Note: the next call to `load_more_events_backwards` can't return
208-
// `WaitForInitialPrevToken` because we've just set to
209-
// `waited_for_initial_prev_token`, so this is not an infinite loop.
210-
//
211-
// Note 2: not a recursive call, because recursive and async have a bad time
212-
// together.
213-
continue;
214-
}
215-
216188
LoadMoreEventsBackwardsOutcome::Gap { prev_token } => {
189+
if prev_token.is_none() && !state_guard.waited_for_initial_prev_token {
190+
// We didn't reload a pagination token, and we haven't waited for one; wait
191+
// and start over.
192+
193+
const DEFAULT_WAIT_FOR_TOKEN_DURATION: Duration = Duration::from_secs(3);
194+
195+
// Release the state guard while waiting, to not deadlock the sync task.
196+
drop(state_guard);
197+
198+
// Otherwise, wait for a notification that we received a previous-batch
199+
// token.
200+
trace!("waiting for a pagination token…");
201+
let _ = timeout(
202+
self.inner.pagination_batch_token_notifier.notified(),
203+
DEFAULT_WAIT_FOR_TOKEN_DURATION,
204+
)
205+
.await;
206+
trace!("done waiting");
207+
208+
self.inner.state.write().await.waited_for_initial_prev_token = true;
209+
210+
// Retry!
211+
//
212+
// Note: the next call to `load_more_events_backwards` can't return
213+
// `WaitForInitialPrevToken` because we've just set to
214+
// `waited_for_initial_prev_token`, so this is not an infinite loop.
215+
//
216+
// Note 2: not a recursive call, because recursive and async have a bad time
217+
// together.
218+
continue;
219+
}
220+
217221
// We have a gap, so resolve it with a network back-pagination.
218222
drop(state_guard);
219223
return self.paginate_backwards_with_network(batch_size, prev_token).await;

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

Lines changed: 5 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -301,10 +301,6 @@ impl RoomEventCache {
301301
// TODO: implement :)
302302
unimplemented!("loading from disk for threads is not implemented yet");
303303
}
304-
305-
LoadMoreEventsBackwardsOutcome::WaitForInitialPrevToken => {
306-
unreachable!("unused for threads")
307-
}
308304
}
309305
}
310306
}
@@ -595,9 +591,6 @@ pub(super) enum LoadMoreEventsBackwardsOutcome {
595591

596592
/// Events have been inserted.
597593
Events { events: Vec<Event>, timeline_event_diffs: Vec<VectorDiff<Event>>, reached_start: bool },
598-
599-
/// The caller must wait for the initial previous-batch token, and retry.
600-
WaitForInitialPrevToken,
601594
}
602595

603596
// Use a private module to hide `events` to this parent module.
@@ -946,23 +939,15 @@ mod private {
946939
// sync for that room, because every room must have *at least* a room creation
947940
// event. Otherwise, we have reached the start of the timeline.
948941

949-
let result = if self.room_linked_chunk.events().next().is_some() {
942+
if self.room_linked_chunk.events().next().is_some() {
950943
// If there's at least one event, this means we've reached the start of the
951944
// timeline, since the chunk is fully loaded.
952945
trace!("chunk is fully loaded and non-empty: reached_start=true");
953-
LoadMoreEventsBackwardsOutcome::StartOfTimeline
954-
} else if !self.waited_for_initial_prev_token {
955-
// There no events. Since we haven't yet, wait for an initial
956-
// previous-token.
957-
LoadMoreEventsBackwardsOutcome::WaitForInitialPrevToken
958-
} else {
959-
// Otherwise, we've already waited, *and* received no previous-batch token
960-
// from the sync, *and* there are still no events in the fully-loaded
961-
// chunk: start back-pagination from the end of the room.
962-
LoadMoreEventsBackwardsOutcome::Gap { prev_token: None }
963-
};
946+
return Ok(LoadMoreEventsBackwardsOutcome::StartOfTimeline);
947+
}
964948

965-
return Ok(result);
949+
// Otherwise, start back-pagination from the end of the room.
950+
return Ok(LoadMoreEventsBackwardsOutcome::Gap { prev_token: None });
966951
}
967952

968953
Err(err) => {

0 commit comments

Comments
 (0)