diff options
author | Erik Johnston <erikj@matrix.org> | 2023-11-16 14:25:35 +0000 |
---|---|---|
committer | GitHub <noreply@github.com> | 2023-11-16 14:25:35 +0000 |
commit | 1b238e88371516bfedb62d010e156820ab164b94 (patch) | |
tree | e7e73a8b70a47651d4d7a5cfbff379ff36828816 /synapse/handlers | |
parent | Fix sending out of order `POSITION` over replication (#16639) (diff) | |
download | synapse-1b238e88371516bfedb62d010e156820ab164b94.tar.xz |
Speed up persisting large number of outliers (#16649)
Recalculating the roots tuple every iteration could be very expensive, so instead let's do a topological sort.
Diffstat (limited to 'synapse/handlers')
-rw-r--r-- | synapse/handlers/federation_event.py | 18 |
1 files changed, 7 insertions, 11 deletions
diff --git a/synapse/handlers/federation_event.py b/synapse/handlers/federation_event.py index ba6b94a8b7..f4c17894aa 100644 --- a/synapse/handlers/federation_event.py +++ b/synapse/handlers/federation_event.py @@ -88,7 +88,7 @@ from synapse.types import ( ) from synapse.types.state import StateFilter from synapse.util.async_helpers import Linearizer, concurrently_execute -from synapse.util.iterutils import batch_iter, partition +from synapse.util.iterutils import batch_iter, partition, sorted_topologically_batched from synapse.util.retryutils import NotRetryingDestination from synapse.util.stringutils import shortstr @@ -1669,14 +1669,13 @@ class FederationEventHandler: # XXX: it might be possible to kick this process off in parallel with fetching # the events. - while event_map: - # build a list of events whose auth events are not in the queue. - roots = tuple( - ev - for ev in event_map.values() - if not any(aid in event_map for aid in ev.auth_event_ids()) - ) + # We need to persist an event's auth events before the event. + auth_graph = { + ev: [event_map[e_id] for e_id in ev.auth_event_ids() if e_id in event_map] + for ev in event_map.values() + } + for roots in sorted_topologically_batched(event_map.values(), auth_graph): if not roots: # if *none* of the remaining events are ready, that means # we have a loop. This either means a bug in our logic, or that @@ -1698,9 +1697,6 @@ class FederationEventHandler: await self._auth_and_persist_outliers_inner(room_id, roots) - for ev in roots: - del event_map[ev.event_id] - async def _auth_and_persist_outliers_inner( self, room_id: str, fetched_events: Collection[EventBase] ) -> None: |