summary refs log tree commit diff
diff options
context:
space:
mode:
authorOlivier 'reivilibre <oliverw@matrix.org>2024-05-18 10:43:40 +0100
committerOlivier 'reivilibre <oliverw@matrix.org>2024-05-18 10:54:03 +0100
commit4fc1ce70f979b74030021254e05807b6d9d1389d (patch)
treeae0713df734726813eb1884ef011988bea9c37e2
parentMerge branch 'release-v1.107' into develop (diff)
downloadsynapse-4fc1ce70f979b74030021254e05807b6d9d1389d.tar.xz
Add logging when sync tokens unexpectedly go backwards
-rw-r--r--synapse/rest/client/sync.py45
1 files changed, 44 insertions, 1 deletions
diff --git a/synapse/rest/client/sync.py b/synapse/rest/client/sync.py
index 2b103ca6a8..c857c658ce 100644
--- a/synapse/rest/client/sync.py
+++ b/synapse/rest/client/sync.py
@@ -45,7 +45,7 @@ from synapse.http.server import HttpServer
 from synapse.http.servlet import RestServlet, parse_boolean, parse_integer, parse_string
 from synapse.http.site import SynapseRequest
 from synapse.logging.opentracing import trace_with_opname
-from synapse.types import JsonDict, Requester, StreamToken
+from synapse.types import JsonDict, Requester, RoomStreamToken, StreamToken
 from synapse.util import json_decoder
 
 from ._base import client_patterns, set_timeline_upper_limit
@@ -238,9 +238,52 @@ class SyncRestServlet(RestServlet):
             time_now, sync_result, requester, filter_collection
         )
 
+        if (
+            since_token is not None
+            and sync_result.next_batch is not None
+            and self._sync_token_went_backwards(
+                since_token.room_key, sync_result.next_batch.room_key
+            )
+        ):
+            since_str = await since_token.to_string(self.store)
+            next_str = await sync_result.next_batch.to_string(self.store)
+            logger.warning(
+                "sync token went backwards! from %s to %s", since_str, next_str
+            )
+
         logger.debug("Event formatting complete")
         return 200, response_content
 
+    def _sync_token_went_backwards(
+        self, since: RoomStreamToken, next: RoomStreamToken
+    ) -> bool:
+        """
+        Returns true if and only if the given token went backwards.
+        """
+        if next.stream < since.stream:
+            return True
+
+        if since.instance_map:
+            for instance, pos in since.instance_map.items():
+                if (
+                    next.instance_map
+                    and next.instance_map.get(instance, next.stream) < pos
+                ):
+                    return True
+                elif next.stream < pos:
+                    return True
+
+        if next.instance_map:
+            for instance, pos in next.instance_map.items():
+                if since.instance_map and pos < since.instance_map.get(
+                    instance, since.stream
+                ):
+                    return True
+                elif pos < since.stream:
+                    return True
+
+        return False
+
     @trace_with_opname("sync.encode_response")
     async def encode_response(
         self,