Don't try and backfill the same room in parallel. (#10116)

If backfilling is slow then the client may time out and retry, causing
Synapse to start a new `/backfill` before the existing backfill has
finished, duplicating work.
This commit is contained in:
Erik Johnston 2021-06-04 10:47:58 +01:00 committed by GitHub
parent c96ab31dff
commit a0cd8ae8cb
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 9 additions and 0 deletions

1
changelog.d/10116.bugfix Normal file
View File

@ -0,0 +1 @@
Fix bug where the server would attempt to fetch the same history in the room from a remote server multiple times in parallel.

View File

@ -178,6 +178,8 @@ class FederationHandler(BaseHandler):
self.room_queues = {} # type: Dict[str, List[Tuple[EventBase, str]]] self.room_queues = {} # type: Dict[str, List[Tuple[EventBase, str]]]
self._room_pdu_linearizer = Linearizer("fed_room_pdu") self._room_pdu_linearizer = Linearizer("fed_room_pdu")
self._room_backfill = Linearizer("room_backfill")
self.third_party_event_rules = hs.get_third_party_event_rules() self.third_party_event_rules = hs.get_third_party_event_rules()
self._ephemeral_messages_enabled = hs.config.enable_ephemeral_messages self._ephemeral_messages_enabled = hs.config.enable_ephemeral_messages
@ -1041,6 +1043,12 @@ class FederationHandler(BaseHandler):
return. This is used as part of the heuristic to decide if we return. This is used as part of the heuristic to decide if we
should back paginate. should back paginate.
""" """
with (await self._room_backfill.queue(room_id)):
return await self._maybe_backfill_inner(room_id, current_depth, limit)
async def _maybe_backfill_inner(
self, room_id: str, current_depth: int, limit: int
) -> bool:
extremities = await self.store.get_oldest_events_with_depth_in_room(room_id) extremities = await self.store.get_oldest_events_with_depth_in_room(room_id)
if not extremities: if not extremities: