atagen

matrix-rust-sdk

public
Star0
Watch0

Commit fce0cc4a7e8c

tarball

atagen <boss@atagen.co>2026-10-25 08:58 UTC

2 files changed+22-24
event-cache: reset loaded views when a store failure clears the room

The pagination and shrink error paths sent a raw Update::Clear for the room, which now also deletes thread and pinned chunks, while memory and the loaded views kept writing against chunk ids that no longer existed. They now go through reset_internal so memory and the views clear with the store, and the pagination path publishes the clear because it returns the error instead of diffs.
Modified file: crates/matrix-sdk/src/event_cache/caches/room/pagination.rs+3 additions−14 deletions
@@ -28,7 +28,7 @@ use eyeball_im::VectorDiff;
2828 use futures_core::{Stream, ready};
2929 use matrix_sdk_base::{
3030 event_cache::{Event, Gap},
31- linked_chunk::{ChunkContent, LinkedChunkId, Update},
31+ linked_chunk::{ChunkContent, LinkedChunkId},
3232 };
3333 use pin_project_lite::pin_project;
3434 use ruma::api::Direction;
@@ -216,11 +216,7 @@ impl PaginatedCache for Arc<RoomEventCacheInner> {
216216 Err(err) => {
217217 error!("error when loading the previous chunk of a linked chunk: {err}");
218218
219- // Clear storage for this room.
220- state
221- .store
222- .handle_linked_chunk_updates(linked_chunk_id, vec![Update::Clear])
223- .await?;
219+ state.reset_after_store_failure().await?;
224220
225221 // Return the error.
226222 return Err(err.into());
@@ -239,14 +235,7 @@ impl PaginatedCache for Arc<RoomEventCacheInner> {
239235 if let Err(err) = state.room_linked_chunk_mut().insert_new_chunk_as_first(new_first_chunk) {
240236 error!("error when inserting the previous chunk into its linked chunk: {err}");
241237
242- // Clear storage for this room.
243- state
244- .store
245- .handle_linked_chunk_updates(
246- LinkedChunkId::Room(&state.state.room_id),
247- vec![Update::Clear],
248- )
249- .await?;
238+ state.reset_after_store_failure().await?;
250239
251240 // Return the error.
252241 return Err(err.into());
Modified file: crates/matrix-sdk/src/event_cache/caches/room/state.rs+19 additions−10 deletions
@@ -30,9 +30,8 @@ use matrix_sdk_base::{
3030 store::{EventCacheStoreLock, EventCacheStoreLockGuard, EventCacheStoreLockState},
3131 },
3232 linked_chunk::{
33- ChunkContent, ChunkIdentifierGenerator, ChunkMetadata, LinkedChunkId, OwnedLinkedChunkId,
34- Position,
35- Update, lazy_loader,
33+ ChunkContent, ChunkMetadata, LinkedChunkId, OwnedLinkedChunkId, Position, Update,
34+ lazy_loader,
3635 },
3736 serde_helpers::{extract_edit_target, extract_thread_root},
3837 sync::Timeline,
@@ -631,13 +630,7 @@ impl<'a> RoomEventCacheStateLockWriteGuard<'a> {
631630 // If loading the last chunk failed, clear the entire linked chunk.
632631 error!("error when reloading a linked chunk from memory: {err}");
633632
634- // Clear storage for this room.
635- self.store
636- .handle_linked_chunk_updates(linked_chunk_id, vec![Update::Clear])
637- .await?;
638-
639- // Restart with an empty linked chunk.
640- (None, ChunkIdentifierGenerator::new_from_scratch())
633+ return self.reset_internal().await;
641634 }
642635 };
643636
@@ -874,6 +867,22 @@ impl<'a> RoomEventCacheStateLockWriteGuard<'a> {
874867 Ok(())
875868 }
876869
870+ /// Reset after a store read failed, publishing the clear right away since
871+ /// the caller returns the failure rather than its diffs.
872+ pub(super) async fn reset_after_store_failure(&mut self) -> Result<(), EventCacheError> {
873+ self.reset_internal().await?;
874+ let diffs = self.state.room_linked_chunk.updates_as_vector_diffs();
875+ self.state.update_sender.send(
876+ RoomEventCacheUpdate::UpdateTimelineEvents(TimelineVectorDiffs {
877+ diffs,
878+ history_gaps: Some(super::history::gap_positions(&self.state.room_linked_chunk)),
879+ origin: EventsOrigin::Cache,
880+ }),
881+ Some(RoomEventCacheGenericUpdate { room_id: self.state.room_id.clone() }),
882+ );
883+ Ok(())
884+ }
885+
877886 async fn reset_internal(&mut self) -> Result<(), EventCacheError> {
878887 let mut replacement = EventLinkedChunk::new();
879888 replacement.reset();