diff --git a/changelog.d/17631.misc b/changelog.d/17631.misc new file mode 100644 index 000000000..2f81356d1 --- /dev/null +++ b/changelog.d/17631.misc @@ -0,0 +1 @@ +Store sliding sync per-connection state in the database. diff --git a/synapse/storage/databases/main/events_bg_updates.py b/synapse/storage/databases/main/events_bg_updates.py index 88ff5aa2d..3160e12bb 100644 --- a/synapse/storage/databases/main/events_bg_updates.py +++ b/synapse/storage/databases/main/events_bg_updates.py @@ -1961,27 +1961,33 @@ class EventsBackgroundUpdatesStore(StreamWorkerStore, StateDeltasStore, SQLBaseS return 0 def _find_previous_membership_txn( - txn: LoggingTransaction, event_id: str, user_id: str + txn: LoggingTransaction, room_id: str, user_id: str, stream_ordering: int ) -> Tuple[str, str]: - # Find the previous invite/knock event before the leave event. This - # is done by looking at the auth events of the invite/knock and - # finding the corresponding membership event. + # Find the previous invite/knock event before the leave event txn.execute( """ - SELECT m.event_id, m.membership - FROM event_auth AS a - INNER JOIN room_memberships AS m ON (a.auth_id = m.event_id) - WHERE a.event_id = ? AND m.user_id = ? + SELECT event_id, membership + FROM room_memberships + WHERE + room_id = ? + AND user_id = ? + AND event_stream_ordering < ? + ORDER BY event_stream_ordering DESC + LIMIT 1 """, - (event_id, user_id), + ( + room_id, + user_id, + stream_ordering, + ), ) row = txn.fetchone() # We should see a corresponding previous invite/knock event assert row is not None - previous_event_id, membership = row + event_id, membership = row - return previous_event_id, membership + return event_id, membership # Map from (room_id, user_id) to ... to_insert_membership_snapshots: Dict[ @@ -2097,8 +2103,9 @@ class EventsBackgroundUpdatesStore(StreamWorkerStore, StateDeltasStore, SQLBaseS await self.db_pool.runInteraction( "sliding_sync_membership_snapshots_bg_update._find_previous_membership", _find_previous_membership_txn, - membership_event_id, + room_id, user_id, + membership_event_stream_ordering, ) ) diff --git a/tests/storage/test_sliding_sync_tables.py b/tests/storage/test_sliding_sync_tables.py index 4be098b6f..d0bbc1c80 100644 --- a/tests/storage/test_sliding_sync_tables.py +++ b/tests/storage/test_sliding_sync_tables.py @@ -270,7 +270,9 @@ class SlidingSyncTablesTestCaseBase(HomeserverTestCase): return invite_room_id, persisted_event def _retract_remote_invite_for_user( - self, user_id: str, remote_room_id: str, invite_event_id: str + self, + user_id: str, + remote_room_id: str, ) -> EventBase: """ Create a fake invite retraction for a remote room and persist it. @@ -283,7 +285,6 @@ class SlidingSyncTablesTestCaseBase(HomeserverTestCase): user_id: The person who was invited and we're going to retract the invite for. remote_room_id: The room ID that the invite was for. - invite_event_id: The event ID of the invite Returns: The persisted leave (kick) event. @@ -297,7 +298,7 @@ class SlidingSyncTablesTestCaseBase(HomeserverTestCase): "origin_server_ts": 1, "type": EventTypes.Member, "content": {"membership": Membership.LEAVE}, - "auth_events": [invite_event_id], + "auth_events": [], "prev_events": [], } @@ -2346,7 +2347,6 @@ class SlidingSyncTablesTestCase(SlidingSyncTablesTestCaseBase): remote_invite_retraction_event = self._retract_remote_invite_for_user( user_id=user1_id, remote_room_id=remote_invite_room_id, - invite_event_id=remote_invite_event.event_id, ) # No one local is joined to the remote room @@ -3580,7 +3580,6 @@ class SlidingSyncTablesBackgroundUpdatesTestCase(SlidingSyncTablesTestCaseBase): room_id_no_info_leave_event = self._retract_remote_invite_for_user( user_id=user1_id, remote_room_id=room_id_no_info, - invite_event_id=room_id_no_info_invite_event.event_id, ) room_id_with_info_leave_event_response = self.helper.leave( room_id_with_info, user1_id, tok=user1_tok @@ -3588,7 +3587,6 @@ class SlidingSyncTablesBackgroundUpdatesTestCase(SlidingSyncTablesTestCaseBase): space_room_id_leave_event = self._retract_remote_invite_for_user( user_id=user1_id, remote_room_id=space_room_id, - invite_event_id=space_room_id_invite_event.event_id, ) # Clean-up the `sliding_sync_membership_snapshots` table as if the inserts did not