Skip to content

Commit 63d2334

Browse files
committed
update #3
1 parent 34193c2 commit 63d2334

File tree

1 file changed

+63
-12
lines changed
  • crates/matrix-sdk/src/event_cache/room

1 file changed

+63
-12
lines changed

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

Lines changed: 63 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -612,7 +612,10 @@ mod private {
612612
deserialized_responses::{ThreadSummary, ThreadSummaryStatus, TimelineEventKind},
613613
event_cache::{
614614
Event, Gap,
615-
store::{DynEventCacheStore, EventCacheStoreLock},
615+
store::{
616+
DynEventCacheStore, EventCacheStoreLock, EventCacheStoreLockGuard,
617+
EventCacheStoreLockState,
618+
},
616619
},
617620
linked_chunk::{
618621
ChunkContent, ChunkIdentifierGenerator, ChunkMetadata, LinkedChunkId,
@@ -707,7 +710,19 @@ mod private {
707710
store: EventCacheStoreLock,
708711
pagination_status: SharedObservable<RoomPaginationStatus>,
709712
) -> Result<Self, EventCacheError> {
710-
let store_lock = store.lock().await?;
713+
let store_guard = match store.lock().await? {
714+
// The lock is clean: all good.
715+
EventCacheStoreLockState::Clean(guard) => guard,
716+
717+
// The lock is dirty: that's not a problem here! Why? Because we are creating the
718+
// state, so it's necessarily new, which means we don't need to refresh it. We must
719+
// clear the dirtiness though.
720+
EventCacheStoreLockState::Dirty(guard) => {
721+
EventCacheStoreLockGuard::clear_dirty(&guard);
722+
723+
guard
724+
}
725+
};
711726

712727
let linked_chunk_id = LinkedChunkId::Room(&room_id);
713728

@@ -716,15 +731,15 @@ mod private {
716731
// If loading the full linked chunk failed, we'll clear the event cache, as it
717732
// indicates that at some point, there's some malformed data.
718733
let full_linked_chunk_metadata =
719-
match Self::load_linked_chunk_metadata(&*store_lock, linked_chunk_id).await {
734+
match Self::load_linked_chunk_metadata(&*store_guard, linked_chunk_id).await {
720735
Ok(metas) => metas,
721736
Err(err) => {
722737
error!(
723738
"error when loading a linked chunk's metadata from the store: {err}"
724739
);
725740

726741
// Try to clear storage for this room.
727-
store_lock
742+
store_guard
728743
.handle_linked_chunk_updates(linked_chunk_id, vec![Update::Clear])
729744
.await?;
730745

@@ -733,7 +748,7 @@ mod private {
733748
}
734749
};
735750

736-
let linked_chunk = match store_lock
751+
let linked_chunk = match store_guard
737752
.load_last_chunk(linked_chunk_id)
738753
.await
739754
.map_err(EventCacheError::from)
@@ -748,7 +763,7 @@ mod private {
748763
);
749764

750765
// Try to clear storage for this room.
751-
store_lock
766+
store_guard
752767
.handle_linked_chunk_updates(linked_chunk_id, vec![Update::Clear])
753768
.await?;
754769

@@ -910,20 +925,32 @@ mod private {
910925
pub(in super::super) async fn load_more_events_backwards(
911926
&mut self,
912927
) -> Result<LoadMoreEventsBackwardsOutcome, EventCacheError> {
928+
let store_guard = match self.store.lock().await? {
929+
// The lock is clean: we don't need to refresh the in-memory state.
930+
EventCacheStoreLockState::Clean(guard) => guard,
931+
932+
// The lock is dirty: we need to refresh the in-memory state before working with it.
933+
EventCacheStoreLockState::Dirty(guard) => {
934+
EventCacheStoreLockGuard::clear_dirty(&guard);
935+
936+
self.shrink_to_last_chunk_with_store_guard(&guard).await?;
937+
938+
guard
939+
}
940+
};
941+
913942
// If any in-memory chunk is a gap, don't load more events, and let the caller
914943
// resolve the gap.
915944
if let Some(prev_token) = self.room_linked_chunk.rgap().map(|gap| gap.prev_token) {
916945
return Ok(LoadMoreEventsBackwardsOutcome::Gap { prev_token: Some(prev_token) });
917946
}
918947

919-
let store = self.store.lock().await?;
920-
921948
let prev_first_chunk =
922949
self.room_linked_chunk.chunks().next().expect("a linked chunk is never empty");
923950

924951
// The first chunk is not a gap, we can load its previous chunk.
925952
let linked_chunk_id = LinkedChunkId::Room(&self.room);
926-
let new_first_chunk = match store
953+
let new_first_chunk = match store_guard
927954
.load_previous_chunk(linked_chunk_id, prev_first_chunk.identifier())
928955
.await
929956
{
@@ -952,7 +979,9 @@ mod private {
952979
error!("error when loading the previous chunk of a linked chunk: {err}");
953980

954981
// Clear storage for this room.
955-
store.handle_linked_chunk_updates(linked_chunk_id, vec![Update::Clear]).await?;
982+
store_guard
983+
.handle_linked_chunk_updates(linked_chunk_id, vec![Update::Clear])
984+
.await?;
956985

957986
// Return the error.
958987
return Err(err.into());
@@ -972,7 +1001,9 @@ mod private {
9721001
error!("error when inserting the previous chunk into its linked chunk: {err}");
9731002

9741003
// Clear storage for this room.
975-
store.handle_linked_chunk_updates(linked_chunk_id, vec![Update::Clear]).await?;
1004+
store_guard
1005+
.handle_linked_chunk_updates(linked_chunk_id, vec![Update::Clear])
1006+
.await?;
9761007

9771008
// Return the error.
9781009
return Err(err.into());
@@ -1011,8 +1042,27 @@ mod private {
10111042
///
10121043
/// Otherwise, returns `None`.
10131044
pub(super) async fn shrink_to_last_chunk(&mut self) -> Result<(), EventCacheError> {
1014-
let store_lock = self.store.lock().await?;
1045+
let store_guard = match self.store.lock().await? {
1046+
// The lock is clean: all good!
1047+
EventCacheStoreLockState::Clean(guard) => guard,
1048+
1049+
// The lock is dirty. We need to refresh the in-memory state. Fortunately for us,
1050+
// that's exactly what this current method does. Let's clear the dirtiness, and
1051+
// let's keep going.
1052+
EventCacheStoreLockState::Dirty(guard) => {
1053+
EventCacheStoreLockGuard::clear_dirty(&guard);
1054+
1055+
guard
1056+
}
1057+
};
1058+
1059+
self.shrink_to_last_chunk_with_store_guard(&store_guard).await
1060+
}
10151061

1062+
async fn shrink_to_last_chunk_with_store_guard(
1063+
&mut self,
1064+
store_lock: &EventCacheStoreLockGuard,
1065+
) -> Result<(), EventCacheError> {
10161066
// Attempt to load the last chunk.
10171067
let linked_chunk_id = LinkedChunkId::Room(&self.room);
10181068
let (last_chunk, chunk_identifier_generator) =
@@ -1081,6 +1131,7 @@ mod private {
10811131
&mut self,
10821132
) -> Result<Vec<VectorDiff<Event>>, EventCacheError> {
10831133
self.shrink_to_last_chunk().await?;
1134+
10841135
Ok(self.room_linked_chunk.updates_as_vector_diffs())
10851136
}
10861137

0 commit comments

Comments
 (0)