From 86b5cb4dbad1f65ebbc43b100cf3fe12fd7f15ab Mon Sep 17 00:00:00 2001 From: Benjamin Bouvier Date: Wed, 26 Feb 2025 11:49:21 +0100 Subject: [PATCH] refactor(event cache): split disk and network paginations into smaller functions --- .../matrix-sdk/src/event_cache/pagination.rs | 48 +++++++++++-------- 1 file changed, 27 insertions(+), 21 deletions(-) diff --git a/crates/matrix-sdk/src/event_cache/pagination.rs b/crates/matrix-sdk/src/event_cache/pagination.rs index e70c31d99..32e83052a 100644 --- a/crates/matrix-sdk/src/event_cache/pagination.rs +++ b/crates/matrix-sdk/src/event_cache/pagination.rs @@ -127,20 +127,13 @@ impl RoomPagination { } async fn run_backwards_impl(&self, batch_size: u16) -> Result> { - const DEFAULT_WAIT_FOR_TOKEN_DURATION: Duration = Duration::from_secs(3); - - // First off, remember that's the `RoomEvents` might be partially loaded - // (because not all events are fully loaded). - // - // Knowing that, if all gaps have been resolved in the linked chunk, let's try - // to load more events from the storage! - - // Try to load one chunk backwards. If it returns events, no need to reach the - // network! + // A linked chunk might not be entirely loaded (if it's been lazy-loaded). Try + // to load from storage first, then from network if storage indicated + // there's no previous events chunk to load. match self.inner.state.write().await.load_more_events_backwards().await? { LoadMoreEventsBackwardsOutcome::Gap => { - // continue, let's resolve this gap! + // We have a gap, so resolve it with a network back-pagination. } LoadMoreEventsBackwardsOutcome::StartOfTimeline => { @@ -168,6 +161,16 @@ impl RoomPagination { } } + // Alright, try network. + self.paginate_backwards_with_network(batch_size).await + } + + async fn paginate_backwards_with_network( + &self, + batch_size: u16, + ) -> Result> { + const DEFAULT_WAIT_FOR_TOKEN_DURATION: Duration = Duration::from_secs(3); + // There is at least one gap that must be resolved; reach the network. // First, ensure there's no other ongoing back-pagination. let prev_status = self.inner.pagination_status.set(RoomPaginationStatus::Paginating); @@ -192,15 +195,21 @@ impl RoomPagination { } }; - let paginator = Paginator::new(self.inner.weak_room.clone()); + let (PaginationResult { events, hit_end_of_timeline: reached_start }, new_gap) = { + // Use a throw-away paginator instance. + let paginator = Paginator::new(self.inner.weak_room.clone()); - paginator - .set_idle_state(PaginatorState::Idle, prev_token.clone(), None) - .expect("a pristine paginator must be in the initial state"); + paginator + .set_idle_state(PaginatorState::Idle, prev_token.clone(), None) + .expect("a pristine paginator must be in the initial state"); - // Run the actual pagination. - let PaginationResult { events, hit_end_of_timeline: reached_start } = - paginator.paginate_backward(batch_size.into()).await?; + // The network request happens here: + let result = paginator.paginate_backward(batch_size.into()).await?; + + let new_gap = paginator.prev_batch_token().map(|prev_token| Gap { prev_token }); + + (result, new_gap) + }; // Make sure the `RoomEvents` isn't updated while we are saving events from // backpagination. @@ -226,9 +235,6 @@ impl RoomPagination { None }; - // The new prev token from this pagination. - let new_gap = paginator.prev_batch_token().map(|prev_token| Gap { prev_token }); - let ( DeduplicationOutcome { all_events: mut events,