diff options
author | Eric Eastwood <erice@element.io> | 2022-09-29 17:24:26 -0500 |
---|---|---|
committer | Eric Eastwood <erice@element.io> | 2022-09-29 17:24:26 -0500 |
commit | 99a623d2095f25909136b60043672a539266e167 (patch) | |
tree | 37969f28624801f3b5235b52f4c87f30d53badbb | |
parent | Don't require `setuptools_rust` at runtime (#13952) (diff) | |
download | synapse-99a623d2095f25909136b60043672a539266e167.tar.xz |
Check appservice user interest against the local users instead of all users
`get_local_users_in_room` is way more performant since it looks at a single table (`local_current_membership`) and is looking through way less data since it only worries about the local users in the room instead of everyone in the room across the federation. Fix https://github.com/matrix-org/synapse/issues/13942 Related to: - https://github.com/matrix-org/synapse/pull/13605 - https://github.com/matrix-org/synapse/pull/13608 - https://github.com/matrix-org/synapse/pull/13606
-rw-r--r-- | synapse/appservice/__init__.py | 10 | ||||
-rw-r--r-- | synapse/handlers/room_member.py | 2 | ||||
-rw-r--r-- | synapse/handlers/user_directory.py | 1 | ||||
-rw-r--r-- | synapse/storage/databases/main/appservice.py | 14 | ||||
-rw-r--r-- | synapse/storage/databases/main/roommember.py | 19 |
5 files changed, 30 insertions, 16 deletions
diff --git a/synapse/appservice/__init__.py b/synapse/appservice/__init__.py index 0dfa00df44..71b534b039 100644 --- a/synapse/appservice/__init__.py +++ b/synapse/appservice/__init__.py @@ -172,15 +172,11 @@ class ApplicationService: Returns: True if this service would like to know about this room. """ - member_list = await store.get_users_in_room( - room_id, on_invalidate=cache_context.invalidate + app_service_users_in_room = await store.get_app_service_users_in_room( + room_id, self, on_invalidate=cache_context.invalidate ) - # check joined member events - for user_id in member_list: - if self.is_interested_in_user(user_id): - return True - return False + return len(app_service_users_in_room) > 0 def is_interested_in_user( self, diff --git a/synapse/handlers/room_member.py b/synapse/handlers/room_member.py index 88158822e0..96cc6eae71 100644 --- a/synapse/handlers/room_member.py +++ b/synapse/handlers/room_member.py @@ -1150,7 +1150,7 @@ class RoomMemberHandler(metaclass=abc.ABCMeta): logger.info("Transferring room state from %s to %s", old_room_id, room_id) # Find all local users that were in the old room and copy over each user's state - users = await self.store.get_users_in_room(old_room_id) + users = await self.store.get_local_users_in_room(old_room_id) await self.copy_user_state_on_room_upgrade(old_room_id, room_id, users) # Add new room to the room directory if the old room was there diff --git a/synapse/handlers/user_directory.py b/synapse/handlers/user_directory.py index 8c3c52e1ca..19df4de439 100644 --- a/synapse/handlers/user_directory.py +++ b/synapse/handlers/user_directory.py @@ -392,6 +392,7 @@ class UserDirectoryHandler(StateDeltasHandler): if is_public: await self.store.add_users_in_public_rooms(room_id, (user_id,)) else: + # TODO: get_local_users_in_room here users_in_room = await self.store.get_users_in_room(room_id) other_users_in_room = [ other diff --git a/synapse/storage/databases/main/appservice.py b/synapse/storage/databases/main/appservice.py index 64b70a7b28..26fd4fa31a 100644 --- a/synapse/storage/databases/main/appservice.py +++ b/synapse/storage/databases/main/appservice.py @@ -157,7 +157,19 @@ class ApplicationServiceWorkerStore(RoomMemberWorkerStore): app_service: "ApplicationService", cache_context: _CacheContext, ) -> List[str]: - users_in_room = await self.get_users_in_room( + """ + Get all users in a room that the appservice controls. + + Args: + room_id: The room to check in. + app_service: The application service to check interest/control against + + Returns: + List of user IDs that the appservice controls. + """ + # We can use `get_local_users_in_room(...)` here because an application + # service can only act on behalf of users of the server it's on. + users_in_room = await self.get_local_users_in_room( room_id, on_invalidate=cache_context.invalidate ) return list(filter(app_service.is_interested_in_user, users_in_room)) diff --git a/synapse/storage/databases/main/roommember.py b/synapse/storage/databases/main/roommember.py index 982e1f08e3..8a9e553397 100644 --- a/synapse/storage/databases/main/roommember.py +++ b/synapse/storage/databases/main/roommember.py @@ -152,13 +152,18 @@ class RoomMemberWorkerStore(EventsWorkerStore): `get_current_hosts_in_room()` and so we can re-use the cache but it's not horrible to have here either. - Uses `m.room.member`s in the room state at the current forward extremities to - determine which users are in the room. - - Will return inaccurate results for rooms with partial state, since the state for - the forward extremities of those rooms will exclude most members. We may also - calculate room state incorrectly for such rooms and believe that a member is or - is not in the room when the opposite is true. + Uses `m.room.member`s in the room state at the current forward + extremities to determine which users are in the room. + + Will return inaccurate results for rooms with partial state, since the + state for the forward extremities of those rooms will exclude most + members. We may also calculate room state incorrectly for such rooms and + believe that a member is or is not in the room when the opposite is + true. + + Note: If you only care about users in the room local to the homeserver, + use `get_local_users_in_room(...)` instead which will be more + performant. """ return await self.db_pool.runInteraction( "get_users_in_room", self.get_users_in_room_txn, room_id |