diff --git a/synapse/storage/databases/main/cache.py b/synapse/storage/databases/main/cache.py index d7bc1474e752..2367ddeea3fd 100644 --- a/synapse/storage/databases/main/cache.py +++ b/synapse/storage/databases/main/cache.py @@ -193,6 +193,9 @@ def _invalidate_caches_for_event( relates_to: Optional[str], backfilled: bool, ) -> None: + # This invalidates any local in-memory cached event objects, the original + # process triggering the invalidation is responsible for clearing any external + # cached objects. self._invalidate_local_get_event_cache(event_id) self.have_seen_event.invalidate((room_id, event_id)) diff --git a/synapse/storage/databases/main/events_worker.py b/synapse/storage/databases/main/events_worker.py index 5b75b3674b0e..27db6f311419 100644 --- a/synapse/storage/databases/main/events_worker.py +++ b/synapse/storage/databases/main/events_worker.py @@ -732,6 +732,11 @@ async def get_missing_events_from_db() -> Dict[str, EventCacheEntry]: return event_entry_map async def _invalidate_get_event_cache(self, event_id: str) -> None: + # First we invalidate the asynchronous cache instance, this may include + # out of process caches such as Redis/memcache. Once complete we can + # invalidate any in memory cache. The ordering is important here to + # ensure we don't pull in any remote invalid value after we invalidate + # the in-memory cache. await self._get_event_cache.invalidate((event_id,)) self._event_ref.pop(event_id, None) self._current_event_fetches.pop(event_id, None) diff --git a/synapse/util/caches/lrucache.py b/synapse/util/caches/lrucache.py index 8e38b7dd05b2..426b911fd9e2 100644 --- a/synapse/util/caches/lrucache.py +++ b/synapse/util/caches/lrucache.py @@ -751,6 +751,7 @@ async def set(self, key: KT, value: VT) -> None: self._lru_cache.set(key, value) async def invalidate(self, key: KT) -> None: + # This method should invalidate any external cache and then invalidate the LruCache. return self._lru_cache.invalidate(key) def invalidate_local(self, key: KT) -> None: