fix(sdk): Events from the Send Queue are inserted in the Event Cache if and only if it is no empty.
This patch fixes a bug where inserting an event from the Send Queue in an empty Event Cache will break the back-pagination logic. Indeed, the detection of the start of the timeline during the back-pagination is conditioned to the emptiness of the cache: - if there is no gap, and if the cache is not empty, then we consider the start of the timeline has been reached. However, if an event from the Send Queue has been inserted, with no previous batch token (because none can be computed at this step), no gap is present and the cache won't be empty, so… this is wrongly assumed to be the start of the timeline. The solution to this problem is to insert the event from the Send Queue if the cache is not empty.
This commit is contained in:
@@ -381,13 +381,7 @@ impl RoomEventCache {
|
||||
|
||||
/// Handle a single event from the `SendQueue`.
|
||||
pub(crate) async fn insert_sent_event_from_send_queue(&self, event: Event) -> Result<()> {
|
||||
self.inner
|
||||
.handle_timeline(
|
||||
Timeline { limited: false, prev_batch: None, events: vec![event] },
|
||||
Vec::new(),
|
||||
BTreeMap::new(),
|
||||
)
|
||||
.await
|
||||
self.inner.insert_sent_event_from_send_queue(event).await
|
||||
}
|
||||
|
||||
/// Save some events in the event cache, for further retrieval with
|
||||
@@ -514,6 +508,22 @@ impl RoomEventCacheInner {
|
||||
timeline: Timeline,
|
||||
ephemeral_events: Vec<Raw<AnySyncEphemeralRoomEvent>>,
|
||||
ambiguity_changes: BTreeMap<OwnedEventId, AmbiguityChange>,
|
||||
) -> Result<()> {
|
||||
self.handle_timeline_inner(
|
||||
self.state.write().await?,
|
||||
timeline,
|
||||
ephemeral_events,
|
||||
ambiguity_changes,
|
||||
)
|
||||
.await
|
||||
}
|
||||
|
||||
async fn handle_timeline_inner(
|
||||
&self,
|
||||
mut state: RoomEventCacheStateLockWriteGuard<'_>,
|
||||
timeline: Timeline,
|
||||
ephemeral_events: Vec<Raw<AnySyncEphemeralRoomEvent>>,
|
||||
ambiguity_changes: BTreeMap<OwnedEventId, AmbiguityChange>,
|
||||
) -> Result<()> {
|
||||
if timeline.events.is_empty()
|
||||
&& timeline.prev_batch.is_none()
|
||||
@@ -527,7 +537,9 @@ impl RoomEventCacheInner {
|
||||
trace!("adding new events");
|
||||
|
||||
let (stored_prev_batch_token, timeline_event_diffs) =
|
||||
self.state.write().await?.handle_sync(timeline, &ephemeral_events).await?;
|
||||
state.handle_sync(timeline, &ephemeral_events).await?;
|
||||
|
||||
drop(state);
|
||||
|
||||
// Now that all events have been added, we can trigger the
|
||||
// `pagination_token_notifier`.
|
||||
@@ -559,6 +571,29 @@ impl RoomEventCacheInner {
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Handle a single event from the `SendQueue`.
|
||||
///
|
||||
/// The event is inserted if and only if the cache is not empty.
|
||||
async fn insert_sent_event_from_send_queue(&self, event: Event) -> Result<()> {
|
||||
let state = self.state.write().await?;
|
||||
|
||||
// Insert the event if the room is not empty, otherwise it can break the
|
||||
// pagination logic when detecting the start of the timeline because no gap can
|
||||
// be inserted properly: it is impossible to compute a `prev_batch` token here.
|
||||
if state.room_linked_chunk().events().next().is_some() {
|
||||
return self
|
||||
.handle_timeline_inner(
|
||||
state,
|
||||
Timeline { limited: false, prev_batch: None, events: vec![event] },
|
||||
Vec::new(),
|
||||
BTreeMap::new(),
|
||||
)
|
||||
.await;
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy)]
|
||||
|
||||
Reference in New Issue
Block a user