-
Notifications
You must be signed in to change notification settings - Fork 429
Pass leave from remote invite rejection down Sliding Sync #18375
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 18 commits
340ae9b
74cd6d5
17cdd4f
5ee188a
de7217f
9e41abd
af7a4af
fd4a633
e0aad4b
1519d4f
7ed2a12
223c87e
b8d1b5e
7640c59
9138ee0
241ec9a
79fc888
3e353b6
a7bc0ca
93b00c3
720f85e
06b9a34
db486c7
06209fc
c9a6a0b
096bbfa
ed7c580
14c4e4d
2c3f74f
1f74e91
5ad092e
b05f339
e876851
ea3c9fc
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1 @@ | ||
| Pass leave from remote invite rejection down Sliding Sync. |
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -80,6 +80,7 @@ | |||||||||||||||||||||||||||||||||||||
| ) | ||||||||||||||||||||||||||||||||||||||
| from synapse.storage.databases.main.events_worker import EventsWorkerStore | ||||||||||||||||||||||||||||||||||||||
| from synapse.storage.engines import BaseDatabaseEngine, PostgresEngine, Sqlite3Engine | ||||||||||||||||||||||||||||||||||||||
| from synapse.storage.roommember import RoomsForUserStateReset | ||||||||||||||||||||||||||||||||||||||
| from synapse.storage.util.id_generators import MultiWriterIdGenerator | ||||||||||||||||||||||||||||||||||||||
| from synapse.types import PersistedEventPosition, RoomStreamToken, StrCollection | ||||||||||||||||||||||||||||||||||||||
| from synapse.util.caches.descriptors import cached, cachedList | ||||||||||||||||||||||||||||||||||||||
|
|
@@ -1136,6 +1137,172 @@ def f(txn: LoggingTransaction) -> List[CurrentStateDeltaMembership]: | |||||||||||||||||||||||||||||||||||||
| if membership_change.room_id not in room_ids_to_exclude | ||||||||||||||||||||||||||||||||||||||
| ] | ||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||
| @trace | ||||||||||||||||||||||||||||||||||||||
| async def get_sliding_sync_membership_changes( | ||||||||||||||||||||||||||||||||||||||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Since this uses the It looks like we're using it in the fallback case as well right now:
As one solution, per the comment in the following code, we could also just make this foreground update now as those tables originally shipped with Synapse 1.115.0rc1 (2024-09-10) (see #17512) and remove the fallback path. synapse/synapse/handlers/sliding_sync/room_lists.py Lines 206 to 223 in d59bbd8
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Hmm, after looking into it a bit, that seems like a large undertaking that would block this fix unnecessarily. I think it may be better to split the impl & keep the old logic for the fallback case.
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I changed it to do just that for now. If we aren't happy with this and want to wait until we have completed the DB transition for sliding sync then that PR will need to be created & merged before we can merge this one.
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Sounds reasonable to me. We may want to consider refactoring We do still have a good set of end-to-end rest layer tests to cover us in a lot of scenarios.
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I agree with the idea. I started down that path but it looks like it'll be quite involved to do properly.
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'm not entirely comfortable merging these changes until those tests have been converted so we can ensure everything is still working as intended.
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Hmm. So after converting that test, 12 of the tests fail when using the new tables (they pass when using the fallback tables). But those same 12 tests also fail against the
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The tests have now been updated & #18399 has been merged. Let's see if these changes are still happy.
MadLittleMods marked this conversation as resolved.
Show resolved
Hide resolved
|
||||||||||||||||||||||||||||||||||||||
| self, | ||||||||||||||||||||||||||||||||||||||
| user_id: str, | ||||||||||||||||||||||||||||||||||||||
| from_key: RoomStreamToken, | ||||||||||||||||||||||||||||||||||||||
| to_key: RoomStreamToken, | ||||||||||||||||||||||||||||||||||||||
| excluded_room_ids: Optional[List[str]] = None, | ||||||||||||||||||||||||||||||||||||||
| ) -> Dict[str, RoomsForUserStateReset]: | ||||||||||||||||||||||||||||||||||||||
| # Start by ruling out cases where a DB query is not necessary. | ||||||||||||||||||||||||||||||||||||||
| if from_key == to_key: | ||||||||||||||||||||||||||||||||||||||
| return {} | ||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||
| if from_key: | ||||||||||||||||||||||||||||||||||||||
| has_changed = self._membership_stream_cache.has_entity_changed( | ||||||||||||||||||||||||||||||||||||||
| user_id, int(from_key.stream) | ||||||||||||||||||||||||||||||||||||||
| ) | ||||||||||||||||||||||||||||||||||||||
| if not has_changed: | ||||||||||||||||||||||||||||||||||||||
| return {} | ||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||
| room_ids_to_exclude: AbstractSet[str] = set() | ||||||||||||||||||||||||||||||||||||||
| if excluded_room_ids is not None: | ||||||||||||||||||||||||||||||||||||||
| room_ids_to_exclude = set(excluded_room_ids) | ||||||||||||||||||||||||||||||||||||||
devonh marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||
| def f(txn: LoggingTransaction) -> Dict[str, RoomsForUserStateReset]: | ||||||||||||||||||||||||||||||||||||||
| # To handle tokens with a non-empty instance_map we fetch more | ||||||||||||||||||||||||||||||||||||||
| # results than necessary and then filter down | ||||||||||||||||||||||||||||||||||||||
| min_from_id = from_key.stream | ||||||||||||||||||||||||||||||||||||||
| max_to_id = to_key.get_max_stream_pos() | ||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||
| # This query looks at membership changes in | ||||||||||||||||||||||||||||||||||||||
| # `sliding_sync_membership_snapshots`. These will not include where | ||||||||||||||||||||||||||||||||||||||
| # users get state reset out of rooms, so we need to look for that | ||||||||||||||||||||||||||||||||||||||
| # case in `current_state_delta_stream`. | ||||||||||||||||||||||||||||||||||||||
devonh marked this conversation as resolved.
Show resolved
Hide resolved
|
||||||||||||||||||||||||||||||||||||||
| # | ||||||||||||||||||||||||||||||||||||||
| # TODO: Add an index a better index on sliding_sync_membership_snapshots | ||||||||||||||||||||||||||||||||||||||
| # probably want: | ||||||||||||||||||||||||||||||||||||||
| # - sliding_sync_membership_snapshots (user_id, event_stream_ordering) | ||||||||||||||||||||||||||||||||||||||
| # replacing the existing index on only (user_id) | ||||||||||||||||||||||||||||||||||||||
| # - MAYBE current_state_delta_stream(state_key, stream_id) WHERE type = 'm.room.member' AND event_id IS NULL | ||||||||||||||||||||||||||||||||||||||
devonh marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||||||||||||||||||||||||||||||||||||||
| sql = """ | ||||||||||||||||||||||||||||||||||||||
| SELECT | ||||||||||||||||||||||||||||||||||||||
| room_id, | ||||||||||||||||||||||||||||||||||||||
| membership_event_id, | ||||||||||||||||||||||||||||||||||||||
| event_instance_name, | ||||||||||||||||||||||||||||||||||||||
| event_stream_ordering, | ||||||||||||||||||||||||||||||||||||||
| membership, | ||||||||||||||||||||||||||||||||||||||
| sender, | ||||||||||||||||||||||||||||||||||||||
| prev_membership, | ||||||||||||||||||||||||||||||||||||||
| room_version | ||||||||||||||||||||||||||||||||||||||
| FROM | ||||||||||||||||||||||||||||||||||||||
| ( | ||||||||||||||||||||||||||||||||||||||
| SELECT | ||||||||||||||||||||||||||||||||||||||
| s.room_id, | ||||||||||||||||||||||||||||||||||||||
| s.membership_event_id, | ||||||||||||||||||||||||||||||||||||||
| s.event_instance_name, | ||||||||||||||||||||||||||||||||||||||
| s.event_stream_ordering, | ||||||||||||||||||||||||||||||||||||||
| s.membership, | ||||||||||||||||||||||||||||||||||||||
| s.sender, | ||||||||||||||||||||||||||||||||||||||
| m_prev.membership AS prev_membership | ||||||||||||||||||||||||||||||||||||||
| FROM sliding_sync_membership_snapshots as s | ||||||||||||||||||||||||||||||||||||||
| LEFT JOIN event_edges AS e ON e.event_id = s.membership_event_id | ||||||||||||||||||||||||||||||||||||||
| LEFT JOIN room_memberships AS m_prev ON m_prev.event_id = e.prev_event_id | ||||||||||||||||||||||||||||||||||||||
| WHERE s.user_id = ? | ||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||
| UNION ALL | ||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||
| SELECT | ||||||||||||||||||||||||||||||||||||||
| s.room_id, | ||||||||||||||||||||||||||||||||||||||
| e.event_id, | ||||||||||||||||||||||||||||||||||||||
| s.instance_name, | ||||||||||||||||||||||||||||||||||||||
| s.stream_id, | ||||||||||||||||||||||||||||||||||||||
| m.membership, | ||||||||||||||||||||||||||||||||||||||
| e.sender, | ||||||||||||||||||||||||||||||||||||||
| m_prev.membership AS prev_membership | ||||||||||||||||||||||||||||||||||||||
| FROM current_state_delta_stream AS s | ||||||||||||||||||||||||||||||||||||||
| LEFT JOIN events AS e ON e.event_id = s.event_id | ||||||||||||||||||||||||||||||||||||||
| LEFT JOIN room_memberships AS m ON m.event_id = s.event_id | ||||||||||||||||||||||||||||||||||||||
| LEFT JOIN room_memberships AS m_prev ON m_prev.event_id = s.prev_event_id | ||||||||||||||||||||||||||||||||||||||
| WHERE | ||||||||||||||||||||||||||||||||||||||
| s.type = ? | ||||||||||||||||||||||||||||||||||||||
| AND s.state_key = ? | ||||||||||||||||||||||||||||||||||||||
| ) AS c | ||||||||||||||||||||||||||||||||||||||
| INNER JOIN rooms USING (room_id) | ||||||||||||||||||||||||||||||||||||||
| WHERE event_stream_ordering > ? AND event_stream_ordering <= ? | ||||||||||||||||||||||||||||||||||||||
| ORDER BY event_stream_ordering ASC | ||||||||||||||||||||||||||||||||||||||
| """ | ||||||||||||||||||||||||||||||||||||||
devonh marked this conversation as resolved.
Show resolved
Hide resolved
|
||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||
| txn.execute( | ||||||||||||||||||||||||||||||||||||||
| sql, | ||||||||||||||||||||||||||||||||||||||
| (user_id, EventTypes.Member, user_id, min_from_id, max_to_id), | ||||||||||||||||||||||||||||||||||||||
| ) | ||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||
| membership_changes: Dict[str, RoomsForUserStateReset] = {} | ||||||||||||||||||||||||||||||||||||||
| for ( | ||||||||||||||||||||||||||||||||||||||
| room_id, | ||||||||||||||||||||||||||||||||||||||
| membership_event_id, | ||||||||||||||||||||||||||||||||||||||
| event_instance_name, | ||||||||||||||||||||||||||||||||||||||
| event_stream_ordering, | ||||||||||||||||||||||||||||||||||||||
| membership, | ||||||||||||||||||||||||||||||||||||||
| sender, | ||||||||||||||||||||||||||||||||||||||
| prev_membership, | ||||||||||||||||||||||||||||||||||||||
| room_version_id, | ||||||||||||||||||||||||||||||||||||||
| ) in txn: | ||||||||||||||||||||||||||||||||||||||
| assert room_id is not None | ||||||||||||||||||||||||||||||||||||||
| assert event_stream_ordering is not None | ||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||
| if room_id in room_ids_to_exclude: | ||||||||||||||||||||||||||||||||||||||
| continue | ||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||
| if _filter_results_by_stream( | ||||||||||||||||||||||||||||||||||||||
| from_key, | ||||||||||||||||||||||||||||||||||||||
| to_key, | ||||||||||||||||||||||||||||||||||||||
| event_instance_name, | ||||||||||||||||||||||||||||||||||||||
| event_stream_ordering, | ||||||||||||||||||||||||||||||||||||||
| ): | ||||||||||||||||||||||||||||||||||||||
| # When the server leaves a room, it will insert new rows into the | ||||||||||||||||||||||||||||||||||||||
| # `current_state_delta_stream` table with `event_id = null` for all | ||||||||||||||||||||||||||||||||||||||
| # current state. This means we might already have a row for the | ||||||||||||||||||||||||||||||||||||||
| # leave event and then another for the same leave where the | ||||||||||||||||||||||||||||||||||||||
| # `event_id=null` but the `prev_event_id` is pointing back at the | ||||||||||||||||||||||||||||||||||||||
| # earlier leave event. We don't want to report the leave, if we | ||||||||||||||||||||||||||||||||||||||
| # already have a leave event. | ||||||||||||||||||||||||||||||||||||||
| if ( | ||||||||||||||||||||||||||||||||||||||
| membership_event_id is None | ||||||||||||||||||||||||||||||||||||||
| and prev_membership == Membership.LEAVE | ||||||||||||||||||||||||||||||||||||||
| ): | ||||||||||||||||||||||||||||||||||||||
| continue | ||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||
| if membership_event_id is None and room_id in membership_changes: | ||||||||||||||||||||||||||||||||||||||
| # SUSPICIOUS: if we join a room and get state reset out of it | ||||||||||||||||||||||||||||||||||||||
| # in the same queried window, | ||||||||||||||||||||||||||||||||||||||
| # won't this ignore the 'state reset out of it' part? | ||||||||||||||||||||||||||||||||||||||
| continue | ||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||
| if membership is None: | ||||||||||||||||||||||||||||||||||||||
| membership = Membership.LEAVE | ||||||||||||||||||||||||||||||||||||||
devonh marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||
| if ( | ||||||||||||||||||||||||||||||||||||||
| membership == Membership.JOIN | ||||||||||||||||||||||||||||||||||||||
| and prev_membership == Membership.JOIN | ||||||||||||||||||||||||||||||||||||||
| ): | ||||||||||||||||||||||||||||||||||||||
| # The user was previously joined so this it not a new join. | ||||||||||||||||||||||||||||||||||||||
| # This happens when the user changes their display name. | ||||||||||||||||||||||||||||||||||||||
| continue | ||||||||||||||||||||||||||||||||||||||
devonh marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||
| membership_change = RoomsForUserStateReset( | ||||||||||||||||||||||||||||||||||||||
| room_id=room_id, | ||||||||||||||||||||||||||||||||||||||
| sender=sender, | ||||||||||||||||||||||||||||||||||||||
| membership=membership, | ||||||||||||||||||||||||||||||||||||||
| event_id=membership_event_id, | ||||||||||||||||||||||||||||||||||||||
| event_pos=PersistedEventPosition( | ||||||||||||||||||||||||||||||||||||||
| event_instance_name, event_stream_ordering | ||||||||||||||||||||||||||||||||||||||
| ), | ||||||||||||||||||||||||||||||||||||||
| room_version_id=room_version_id, | ||||||||||||||||||||||||||||||||||||||
| ) | ||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||
| membership_changes[room_id] = membership_change | ||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||
| return membership_changes | ||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||
| membership_changes = await self.db_pool.runInteraction( | ||||||||||||||||||||||||||||||||||||||
| "get_sliding_sync_membership_changes", f | ||||||||||||||||||||||||||||||||||||||
| ) | ||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||
| return membership_changes | ||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||
| @cancellable | ||||||||||||||||||||||||||||||||||||||
| async def get_membership_changes_for_user( | ||||||||||||||||||||||||||||||||||||||
| self, | ||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||
Uh oh!
There was an error while loading. Please reload this page.