fix(ffi): use EventCache::clear_all_rooms() to clear the events caches

Clearing only the store backend, while not emptying the in-memory linked
chunks, will lead to out-of-sync state across the in-memory caches and
the database. As a result, it's safer to call the existing
`EventCacheInner::clear_all_rooms`, which will clear all the rooms
manually.
This commit is contained in:
Benjamin Bouvier
2025-04-01 15:53:51 +02:00
parent d30dc7177f
commit 42133a60c8
3 changed files with 18 additions and 6 deletions

View File

@@ -1208,13 +1208,14 @@ impl Client {
/// retention policy.
pub async fn clear_caches(&self) -> Result<(), ClientError> {
let closure = async || -> Result<_, EventCacheError> {
let store = self.inner.event_cache_store().lock().await?;
// Clear all the room chunks.
store.clear_all_rooms_chunks().await?;
// Clean up the media cache according to the current media retention policy.
store.clean_up_media_cache().await?;
self.inner.event_cache_store().lock().await?.clean_up_media_cache().await?;
// Clear all the room chunks. It's important to *not* call
// `EventCacheStore::clear_all_rooms_chunks` here, because there might be live
// observers of the linked chunks, and that would cause some very bad state
// mismatch.
self.inner.event_cache().clear_all_rooms().await?;
Ok(())
};

View File

@@ -101,6 +101,10 @@ pub trait EventCacheStore: AsyncTraitDeps {
/// using the above [`Self::handle_linked_chunk_updates`] methods. It
/// must *also* delete all the events' content, if they were stored in a
/// separate table.
///
/// ⚠ This is meant only for super specific use cases, where there shouldn't
/// be any live in-memory linked chunks. In general, prefer using
/// `EventCache::clear_all_rooms()` from the common SDK crate.
async fn clear_all_rooms_chunks(&self) -> Result<(), Self::Error>;
/// Given a set of event IDs, return the duplicated events along with their

View File

@@ -361,6 +361,13 @@ impl EventCache {
Ok((room, drop_handles))
}
/// Cleanly clear all the rooms' event caches.
///
/// This will notify any live observers that the room has been cleared.
pub async fn clear_all_rooms(&self) -> Result<()> {
self.inner.clear_all_rooms().await
}
/// Add an initial set of events to the event cache, reloaded from a cache.
///
/// TODO: temporary for API compat, as the event cache should take care of