-
Notifications
You must be signed in to change notification settings - Fork 421
Description
Description:
I tried creating a new server and setting up federation between the old and the new servers. When a user is invited to a federated room, they don’t see the full room history — it seems that federation only provides a limited amount of history (about 100 messages). The room’s history visibility is set to “since the point in time this option was selected”, so I’m not referring to rooms where history visibility is set to “since they were invited” or “since they joined.”
After checking the Synapse source code, specifically synapse/handlers/federation.py, I found that the function try_backfill has a hardcoded limit=100.
synapse/synapse/handlers/federation.py
Lines 446 to 540 in dc7f01f
| async def try_backfill(domains: StrCollection) -> bool: | |
| # TODO: Should we try multiple of these at a time? | |
| # Number of contacted remote homeservers that have denied our backfill | |
| # request with a 4xx code. | |
| denied_count = 0 | |
| # Maximum number of contacted remote homeservers that can deny our | |
| # backfill request with 4xx codes before we give up. | |
| max_denied_count = 5 | |
| for dom in domains: | |
| # We don't want to ask our own server for information we don't have | |
| if self.is_mine_server_name(dom): | |
| continue | |
| try: | |
| await self._federation_event_handler.backfill( | |
| dom, room_id, limit=100, extremities=extremities_to_request | |
| ) | |
| # If this succeeded then we probably already have the | |
| # appropriate stuff. | |
| # TODO: We can probably do something more intelligent here. | |
| return True | |
| except NotRetryingDestination as e: | |
| logger.info("_maybe_backfill_inner: %s", e) | |
| continue | |
| except FederationDeniedError: | |
| logger.info( | |
| "_maybe_backfill_inner: Not attempting to backfill from %s because the homeserver is not on our federation whitelist", | |
| dom, | |
| ) | |
| continue | |
| except (SynapseError, InvalidResponseError) as e: | |
| logger.info("Failed to backfill from %s because %s", dom, e) | |
| continue | |
| except HttpResponseException as e: | |
| if 400 <= e.code < 500: | |
| logger.warning( | |
| "Backfill denied from %s because %s [%d/%d]", | |
| dom, | |
| e, | |
| denied_count, | |
| max_denied_count, | |
| ) | |
| denied_count += 1 | |
| if denied_count >= max_denied_count: | |
| return False | |
| continue | |
| logger.info("Failed to backfill from %s because %s", dom, e) | |
| continue | |
| except CodeMessageException as e: | |
| if 400 <= e.code < 500: | |
| logger.warning( | |
| "Backfill denied from %s because %s [%d/%d]", | |
| dom, | |
| e, | |
| denied_count, | |
| max_denied_count, | |
| ) | |
| denied_count += 1 | |
| if denied_count >= max_denied_count: | |
| return False | |
| continue | |
| logger.info("Failed to backfill from %s because %s", dom, e) | |
| continue | |
| except RequestSendFailed as e: | |
| logger.info("Failed to get backfill from %s because %s", dom, e) | |
| continue | |
| except Exception as e: | |
| logger.exception("Failed to backfill from %s because %s", dom, e) | |
| continue | |
| return False | |
| # If we have the `processing_start_time`, then we can make an | |
| # observation. We wouldn't have the `processing_start_time` in the case | |
| # where `_maybe_backfill_inner` is recursively called to find any | |
| # backfill points regardless of `current_depth`. | |
| if processing_start_time is not None: | |
| processing_end_time = self.clock.time_msec() | |
| backfill_processing_before_timer.labels( | |
| **{SERVER_NAME_LABEL: self.server_name} | |
| ).observe((processing_end_time - processing_start_time) / 1000) | |
| success = await try_backfill(likely_domains) | |
| if success: | |
| return True | |
| # TODO: we could also try servers which were previously in the room, but | |
| # are no longer. | |
| return False |
Potential solutions
Would it be possible to change this limit through homeserver.yaml? Or is there a specific reason why this value is hardcoded?