feat(sdk): Allow to reset an EventFocusedCache.

This patch updates `ResetCaches` to handle the event-focused caches.
This commit is contained in:
Ivan Enderlin
2026-05-21 17:55:35 +02:00
parent 53839f0318
commit 86bc97911c
2 changed files with 79 additions and 9 deletions

View File

@@ -31,6 +31,7 @@
use std::sync::Arc;
use eyeball_im::VectorDiff;
use matrix_sdk_base::{
deserialized_responses::TimelineEvent,
event_cache::{Event, Gap},
@@ -90,7 +91,7 @@ pub(crate) enum EventFocusedPaginationMode {
},
}
struct EventFocusedCacheState {
pub(super) struct EventFocusedCacheState {
/// The room owning this event-focused cache.
room: WeakRoom,
@@ -503,6 +504,24 @@ impl EventFocusedCacheState {
Ok((result.chunk, result.next_batch_token))
}
/// Reset this data structure as if it were brand new.
///
/// Return a single diff update that is a clear of all events; as a
/// result, the caller may override any pending diff updates
/// with the result of this function.
pub fn reset(&mut self) -> Result<Vec<VectorDiff<Event>>> {
self.chunk.reset();
self.propagate_changes();
let diff_updates = self.chunk.updates_as_vector_diffs();
// Ensure the contract defined in the doc comment is true:
debug_assert_eq!(diff_updates.len(), 1);
debug_assert!(matches!(diff_updates[0], VectorDiff::Clear));
Ok(diff_updates)
}
}
/// A cache for an event-focused timeline.
@@ -543,6 +562,16 @@ impl EventFocusedCache {
}
}
/// Return a reference to the state.
pub(super) fn state(&self) -> &Arc<RwLock<EventFocusedCacheState>> {
&self.inner
}
/// Get a reference to the _update sender_.
pub(super) async fn update_sender(&self) -> EventFocusedCacheUpdateSender {
self.inner.read().await.sender.clone()
}
/// Subscribe to updates from this event-focused timeline.
pub async fn subscribe(&self) -> (Vec<Event>, Receiver<TimelineVectorDiffs>) {
let inner = self.inner.read().await;

View File

@@ -430,6 +430,13 @@ pub(super) struct ResetCaches<'c> {
pinned_events::PinnedEventsCacheStateLockWriteGuard<'c>,
pinned_events::PinnedEventsCacheUpdateSender,
)>,
event_focused_lock: OwnedRwLockWriteGuard<
HashMap<event_focused::EventFocusedCacheKey, event_focused::EventFocusedCache>,
>,
event_focused_locks: Vec<(
OwnedRwLockWriteGuard<event_focused::EventFocusedCacheState>,
event_focused::EventFocusedCacheUpdateSender,
)>,
}
impl<'c> ResetCaches<'c> {
@@ -459,11 +466,26 @@ impl<'c> ResetCaches<'c> {
None
};
// TODO (in next commits).
let _ = event_focused;
todo!();
// Acquire an exclusive access to the event-focused caches.
// Then, for each event-focused, acquire an exclusive access to its state.
let event_focused_lock = event_focused.clone().write_owned().await;
let mut event_focused_locks = Vec::new();
Ok(Self { room_lock, threads_lock, thread_locks, pinned_events_lock })
for event_focused in event_focused_lock.values() {
event_focused_locks.push((
event_focused.state().clone().write_owned().await,
event_focused.update_sender().await,
));
}
Ok(Self {
room_lock,
threads_lock,
thread_locks,
pinned_events_lock,
event_focused_lock,
event_focused_locks,
})
}
/// Reset all the event caches, and broadcast the [`TimelineVectorDiffs`].
@@ -473,7 +495,14 @@ impl<'c> ResetCaches<'c> {
///
/// It can fail if resetting an event cache fails.
pub async fn reset_all(self) -> Result<()> {
let Self { room_lock, threads_lock, thread_locks, pinned_events_lock } = self;
let Self {
room_lock,
threads_lock,
thread_locks,
pinned_events_lock,
event_focused_lock,
event_focused_locks,
} = self;
// Room.
{
@@ -491,9 +520,7 @@ impl<'c> ResetCaches<'c> {
// Threads.
{
for thread_lock in thread_locks {
let (mut thread_state, thread_update_sender) = thread_lock;
for (mut thread_state, thread_update_sender) in thread_locks {
let updates_as_vector_diffs = thread_state.reset().await?;
thread_update_sender.send(
TimelineVectorDiffs {
@@ -522,6 +549,20 @@ impl<'c> ResetCaches<'c> {
}
}
// Event-focused.
{
for (mut event_focused_state, event_focused_update_sender) in event_focused_locks {
let updates_as_vector_diffs = event_focused_state.reset()?;
let _ = event_focused_update_sender.send(TimelineVectorDiffs {
diffs: updates_as_vector_diffs,
origin: EventsOrigin::Cache,
});
}
// Now we can release the exclusive access over the event-focused caches.
drop(event_focused_lock);
}
Ok(())
}
}