summary refs log tree commit diff
path: root/synapse
diff options
context:
space:
mode:
authorErik Johnston <erik@matrix.org>2024-07-30 16:04:22 +0100
committerErik Johnston <erik@matrix.org>2024-07-30 16:04:22 +0100
commit25ddb424c647688954213bd8799ff2b9c8637ee5 (patch)
treed2280555fdd827362a774ee91c3f6e8a87ca393a /synapse
parentMerge remote-tracking branch 'origin/develop' into erikj/ss_hacks (diff)
parentHandle increases in timeline limit (diff)
downloadsynapse-25ddb424c647688954213bd8799ff2b9c8637ee5.tar.xz
Merge branch 'erikj/ss_room_sub_timeline' into erikj/ss_hacks
Diffstat (limited to 'synapse')
-rw-r--r--synapse/handlers/sliding_sync.py77
1 files changed, 55 insertions, 22 deletions
diff --git a/synapse/handlers/sliding_sync.py b/synapse/handlers/sliding_sync.py

index ebb15a8451..a38ff32a71 100644 --- a/synapse/handlers/sliding_sync.py +++ b/synapse/handlers/sliding_sync.py
@@ -660,6 +660,13 @@ class SlidingSyncHandler: else: assert_never(status.status) + if status.timeline_limit is not None and ( + status.timeline_limit < relevant_room_map[room_id].timeline_limit + ): + # If the timeline limit has increased we want to send down + # more historic events (even if nothing has since changed). + rooms_should_send.add(room_id) + # We only need to check for new events since any state changes # will also come down as new events. rooms_that_have_updates = self.store.get_rooms_that_might_have_updates( @@ -705,7 +712,7 @@ class SlidingSyncHandler: if has_lists or has_room_subscriptions: connection_position = await self.connection_store.record_rooms( sync_config=sync_config, - relevant_room_map=relevant_room_map, + room_configs=relevant_room_map, from_token=from_token, sent_room_ids=relevant_room_map.keys(), # TODO: We need to calculate which rooms have had updates since the `from_token` but were not included in the `sent_room_ids` @@ -1484,7 +1491,12 @@ class SlidingSyncHandler: # - When users `newly_joined` # - For an incremental sync where we haven't sent it down this # connection before + # + # We also decide if we should ignore the timeline bound or not. This is + # to handle the case where the client has requested more historical + # messages in the room by increasing the timeline limit. from_bound = None + ignore_timeline_bound = False initial = True if from_token and not room_membership_for_user_at_to_token.newly_joined: room_status = await self.connection_store.have_sent_room( @@ -1492,6 +1504,7 @@ class SlidingSyncHandler: connection_token=from_token.connection_position, room_id=room_id, ) + if room_status.status == HaveSentRoomFlag.LIVE: from_bound = from_token.stream_token.room_key initial = False @@ -1505,15 +1518,24 @@ class SlidingSyncHandler: else: assert_never(room_status.status) - if ( - room_status.timeline_limit is not None - and room_status.timeline_limit < room_sync_config.timeline_limit + if room_status.timeline_limit is not None and ( + room_status.timeline_limit < room_sync_config.timeline_limit ): - from_bound = None + # If the timeline limit has been increased since previous + # requests then we treat it as request for more events. We do + # this by sending down a `limited` sync, ignoring the from + # bound. + ignore_timeline_bound = True log_kv({"sliding_sync.room_status": room_status}) - log_kv({"sliding_sync.from_bound": from_bound, "sliding_sync.initial": initial}) + log_kv( + { + "sliding_sync.from_bound": from_bound, + "sliding_sync.ignore_timeline_bound": ignore_timeline_bound, + "sliding_sync.initial": initial, + } + ) # Assemble the list of timeline events # @@ -1560,7 +1582,7 @@ class SlidingSyncHandler: # (from newer to older events) starting at to_bound. # This ensures we fill the `limit` with the newest events first, from_key=to_bound, - to_key=from_bound, + to_key=from_bound if not ignore_timeline_bound else None, direction=Direction.BACKWARDS, # We add one so we can determine if there are enough events to saturate # the limit or not (see `limited`) @@ -2380,6 +2402,9 @@ class HaveSentRoom: contains the last stream token of the last updates we sent down the room, i.e. we still need to send everything since then to the client. + timeline_limit: The timeline limit config for the room, if LIVE or + PREVIOUSLY. This is used to track if the client has increased + the timeline limit to request more events. """ status: HaveSentRoomFlag @@ -2387,13 +2412,16 @@ class HaveSentRoom: timeline_limit: Optional[int] @staticmethod + def live(timeline_limit: int) -> "HaveSentRoom": + return HaveSentRoom(HaveSentRoomFlag.LIVE, None, timeline_limit) + + @staticmethod def previously(last_token: RoomStreamToken, timeline_limit: int) -> "HaveSentRoom": """Constructor for `PREVIOUSLY` flag.""" return HaveSentRoom(HaveSentRoomFlag.PREVIOUSLY, last_token, timeline_limit) HAVE_SENT_ROOM_NEVER = HaveSentRoom(HaveSentRoomFlag.NEVER, None, None) -HAVE_SENT_ROOM_LIVE = HaveSentRoom(HaveSentRoomFlag.LIVE, None, None) @attr.s(auto_attribs=True) @@ -2448,7 +2476,7 @@ class SlidingSyncConnectionStore: async def record_rooms( self, sync_config: SlidingSyncConfig, - relevant_room_map: Dict[str, RoomSyncConfig], + room_configs: Dict[str, RoomSyncConfig], from_token: Optional[SlidingSyncStreamToken], *, sent_room_ids: StrCollection, @@ -2489,8 +2517,12 @@ class SlidingSyncConnectionStore: # end we can treat this as a noop. have_updated = False for room_id in sent_room_ids: - new_room_statuses[room_id] = HAVE_SENT_ROOM_LIVE - have_updated = True + prev_state = new_room_statuses.get(room_id) + new_room_statuses[room_id] = HaveSentRoom.live( + room_configs[room_id].timeline_limit + ) + if prev_state != new_room_statuses[room_id]: + have_updated = True # Whether we add/update the entries for unsent rooms depends on the # existing entry: @@ -2501,21 +2533,22 @@ class SlidingSyncConnectionStore: # given token, so we don't need to update the entry. # - NEVER: We have never previously sent down the room, and we haven't # sent anything down this time either so we leave it as NEVER. + # + # We only need to do this if `from_token` is not None, as if it is then + # we know that there are no existing entires. - # Work out the new state for unsent rooms that were `LIVE`. - - for room_id in unsent_room_ids: - prev_state = new_room_statuses.get(room_id) - if prev_state is not None and prev_state.status == HaveSentRoomFlag.LIVE: - have_updated = True - - if from_token: + if from_token: + for room_id in unsent_room_ids: + prev_state = new_room_statuses.get(room_id) + if ( + prev_state is not None + and prev_state.status == HaveSentRoomFlag.LIVE + ): new_room_statuses[room_id] = HaveSentRoom.previously( from_token.stream_token.room_key, - relevant_room_map[room_id].timeline_limit, + room_configs[room_id].timeline_limit, ) - else: - new_room_statuses[room_id] = HAVE_SENT_ROOM_NEVER + have_updated = True if not have_updated: return prev_connection_token