diff --git a/synapse/handlers/sliding_sync.py b/synapse/handlers/sliding_sync.py
index 8467766518..1936471345 100644
--- a/synapse/handlers/sliding_sync.py
+++ b/synapse/handlers/sliding_sync.py
@@ -47,6 +47,7 @@ from synapse.api.constants import (
EventTypes,
Membership,
)
+from synapse.api.errors import SlidingSyncUnknownPosition
from synapse.events import EventBase, StrippedStateEvent
from synapse.events.utils import parse_stripped_state_event, strip_event
from synapse.handlers.relations import BundledAggregations
@@ -491,6 +492,22 @@ class SlidingSyncHandler:
# See https://github.com/matrix-org/matrix-doc/issues/1144
raise NotImplementedError()
+ if from_token:
+ # Check that we recognize the connection position, if not tell the
+ # clients that they need to start again.
+ #
+ # If we don't do this and the client asks for the full range of
+ # rooms, we end up sending down all rooms and their state from
+ # scratch (which can be very slow). By expiring the connection we
+ # allow the client a chance to do an initial request with a smaller
+ # range of rooms to get them some results sooner but will end up
+ # taking the same amount of time (more with round-trips and
+ # re-processing) in the end to get everything again.
+ if not await self.connection_store.is_valid_token(
+ sync_config, from_token.connection_position
+ ):
+ raise SlidingSyncUnknownPosition()
+
await self.connection_store.mark_token_seen(
sync_config=sync_config,
from_token=from_token,
@@ -2821,6 +2838,16 @@ class SlidingSyncConnectionStore:
attr.Factory(dict)
)
+ async def is_valid_token(
+ self, sync_config: SlidingSyncConfig, connection_token: int
+ ) -> bool:
+ """Return whether the connection token is valid/recognized"""
+ if connection_token == 0:
+ return True
+
+ conn_key = self._get_connection_key(sync_config)
+ return connection_token in self._connections.get(conn_key, {})
+
async def have_sent_room(
self, sync_config: SlidingSyncConfig, connection_token: int, room_id: str
) -> HaveSentRoom:
|