Skip to content
This repository has been archived by the owner on Apr 26, 2024. It is now read-only.

Optimise async get event lookups #13435

Merged
merged 11 commits into from
Aug 4, 2022
2 changes: 1 addition & 1 deletion changelog.d/13435.misc
Original file line number Diff line number Diff line change
@@ -1 +1 @@
Prevent unnecessary lookups to any external get event cache. Contributed by Nick @ Beeper (@fizzadar).
Prevent unnecessary lookups to any external `get_event` cache. Contributed by Nick @ Beeper (@fizzadar).
35 changes: 28 additions & 7 deletions synapse/storage/databases/main/events_worker.py
Original file line number Diff line number Diff line change
Expand Up @@ -602,7 +602,8 @@ async def _get_events_from_cache_or_db(
"""
# Shortcut: check if we have any events in the *in memory* cache - this function
# may be called repeatedly for the same event so at this point we cannot reach
# out to any external cache for performance reasons.
# out to any external cache for performance reasons, this is done later on in
# the `get_missing_events_from_cache_or_db` function below.
Fizzadar marked this conversation as resolved.
Show resolved Hide resolved
event_entry_map = self._get_events_from_local_cache(
event_ids,
)
Expand Down Expand Up @@ -664,14 +665,13 @@ async def get_missing_events_from_cache_or_db() -> Dict[
#
missing_events = {}
try:
# First fetch from the cache - including any external caches
cache_missing_events = await self._get_events_from_cache(
# Try to fetch from any external cache, in-memory cache checked above
Fizzadar marked this conversation as resolved.
Show resolved Hide resolved
missing_events = await self._get_events_from_external_cache(
missing_events_ids,
)
missing_events.update(cache_missing_events)
# Now actually fetch any remaining events from the DB
db_missing_events = await self._get_events_from_db(
missing_events_ids - set(cache_missing_events.keys()),
missing_events_ids - missing_events.keys(),
)
missing_events.update(db_missing_events)
except Exception as e:
Expand Down Expand Up @@ -780,9 +780,30 @@ async def _get_events_from_cache(
)

missing_event_ids = {e for e in events if e not in event_map}
Fizzadar marked this conversation as resolved.
Show resolved Hide resolved
event_map.update(
await self._get_events_from_external_cache(
events=missing_event_ids,
update_metrics=update_metrics,
)
)

return event_map

async def _get_events_from_external_cache(
self, events: Iterable[str], update_metrics: bool = True
) -> Dict[str, EventCacheEntry]:
"""Fetch events from any configured external cache.

May return rejected events.

Args:
events: list of event_ids to fetch
update_metrics: Whether to update the cache hit ratio metrics
"""
event_map = {}

for event_id in missing_event_ids:
ret = await self._get_event_cache.get(
for event_id in events:
ret = await self._get_event_cache.get_external(
(event_id,), None, update_metrics=update_metrics
)
if ret:
Expand Down
9 changes: 9 additions & 0 deletions synapse/util/caches/lrucache.py
Original file line number Diff line number Diff line change
Expand Up @@ -834,6 +834,15 @@ async def get(
) -> Optional[VT]:
return self._lru_cache.get(key, update_metrics=update_metrics)

async def get_external(
self,
key: KT,
default: Optional[T] = None,
update_metrics: bool = True,
) -> Optional[VT]:
# This method should fetch from any configured external cache, in this case noop.
return None

def get_local(
self, key: KT, default: Optional[T] = None, update_metrics: bool = True
) -> Optional[VT]:
Expand Down