From 7b9897db98e7e96086951b0562e875968a102278 Mon Sep 17 00:00:00 2001 From: Erik Johnston Date: Fri, 4 Oct 2024 10:59:41 +0100 Subject: [PATCH] Omit bump stamp when it is unchanged --- synapse/handlers/sliding_sync/__init__.py | 51 +++++++++++++++++------ synapse/rest/client/sync.py | 4 +- synapse/types/handlers/sliding_sync.py | 3 +- 3 files changed, 43 insertions(+), 15 deletions(-) diff --git a/synapse/handlers/sliding_sync/__init__.py b/synapse/handlers/sliding_sync/__init__.py index 9fcc68ff25..5bc38ec088 100644 --- a/synapse/handlers/sliding_sync/__init__.py +++ b/synapse/handlers/sliding_sync/__init__.py @@ -1048,22 +1048,34 @@ async def get_room_sync_data( ) ) - # Figure out the last bump event in the room - # - # By default, just choose the membership event position for any non-join membership - bump_stamp = room_membership_for_user_at_to_token.event_pos.stream + # Figure out the last bump event in the room. If the bump stamp hasn't + # changed we omit it from the response. + bump_stamp = None + + always_return_bump_stamp = ( + room_membership_for_user_at_to_token.membership != Membership.JOIN + or limited is not False + or initial + ) + # If we're joined to the room, we need to find the last bump event before the # `to_token` if room_membership_for_user_at_to_token.membership == Membership.JOIN: - # Try and get a bump stamp, if not we just fall back to the - # membership token. + # Try and get a bump stamp new_bump_stamp = await self._get_bump_stamp( - room_id, to_token, timeline_events + room_id, + to_token, + timeline_events, + check_non_timeline=always_return_bump_stamp, ) if new_bump_stamp is not None: bump_stamp = new_bump_stamp - if bump_stamp < 0: + if bump_stamp is None and always_return_bump_stamp: + # By default, just choose the membership event position for any non-join membership + bump_stamp = room_membership_for_user_at_to_token.event_pos.stream + + if bump_stamp is not None and bump_stamp < 0: # We never want to send down negative stream orderings, as you can't # sensibly compare positive and negative stream orderings (they have # different meanings). @@ -1156,14 +1168,22 @@ async def get_room_sync_data( @trace async def _get_bump_stamp( - self, room_id: str, to_token: StreamToken, timeline: List[EventBase] + self, + room_id: str, + to_token: StreamToken, + timeline: List[EventBase], + check_non_timeline: bool, ) -> Optional[int]: - """Get a bump stamp for the room, if we have a bump event + """Get a bump stamp for the room, if we have a bump event and it has + changed. Args: - room_id - to_token: The upper bound of token to return - timeline: The list of events we have fetched. + room_id to_token: The upper bound of token to return timeline: The + list of events we have fetched. limited: If the timeline was + limited. + check_non_timeline: Whether we need to check for bump stamp for + events before the timeline if we didn't find a bump stamp in + the timeline events. """ # First check the timeline events we're returning to see if one of @@ -1183,6 +1203,11 @@ async def _get_bump_stamp( if new_bump_stamp > 0: return new_bump_stamp + if not check_non_timeline: + # If we are not a limited sync, then we know the bump stamp can't + # have changed. + return None + # We can quickly query for the latest bump event in the room using the # sliding sync tables. latest_room_bump_stamp = await self.store.get_latest_bump_stamp_for_room( diff --git a/synapse/rest/client/sync.py b/synapse/rest/client/sync.py index 364cf40153..122708e933 100644 --- a/synapse/rest/client/sync.py +++ b/synapse/rest/client/sync.py @@ -1010,11 +1010,13 @@ async def encode_rooms( serialized_rooms: Dict[str, JsonDict] = {} for room_id, room_result in rooms.items(): serialized_rooms[room_id] = { - "bump_stamp": room_result.bump_stamp, "notification_count": room_result.notification_count, "highlight_count": room_result.highlight_count, } + if room_result.bump_stamp is not None: + serialized_rooms[room_id]["bump_stamp"] = room_result.bump_stamp + if room_result.joined_count is not None: serialized_rooms[room_id]["joined_count"] = room_result.joined_count diff --git a/synapse/types/handlers/sliding_sync.py b/synapse/types/handlers/sliding_sync.py index 5dd2c9d411..05a42c68ee 100644 --- a/synapse/types/handlers/sliding_sync.py +++ b/synapse/types/handlers/sliding_sync.py @@ -158,6 +158,7 @@ class RoomResult: name changes to mark the room as unread and bump it to the top. For encrypted rooms, we just have to consider any activity as a bump because we can't see the content and the client has to figure it out for themselves. + This is only included if there has been a change. joined_count: The number of users with membership of join, including the client's own user ID. (same as sync `v2 m.joined_member_count`) invited_count: The number of users with membership of invite. (same as sync v2 @@ -193,7 +194,7 @@ class StrippedHero: limited: Optional[bool] # Only optional because it won't be included for invite/knock rooms with `stripped_state` num_live: Optional[int] - bump_stamp: int + bump_stamp: Optional[int] joined_count: Optional[int] invited_count: Optional[int] notification_count: int