Skip to content
This repository has been archived by the owner on Apr 26, 2024. It is now read-only.

Commit

Permalink
Check appservice user interest against the local users instead of all…
Browse files Browse the repository at this point in the history
… 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 #13942

Related to:

 - #13605
 - #13608
 - #13606
  • Loading branch information
MadLittleMods committed Sep 29, 2022
1 parent 6f0c3e6 commit 99a623d
Show file tree
Hide file tree
Showing 5 changed files with 30 additions and 16 deletions.
10 changes: 3 additions & 7 deletions synapse/appservice/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -172,15 +172,11 @@ async def _matches_user_in_member_list(
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,
Expand Down
2 changes: 1 addition & 1 deletion synapse/handlers/room_member.py
Original file line number Diff line number Diff line change
Expand Up @@ -1150,7 +1150,7 @@ async def transfer_room_state_on_room_upgrade(
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
Expand Down
1 change: 1 addition & 0 deletions synapse/handlers/user_directory.py
Original file line number Diff line number Diff line change
Expand Up @@ -392,6 +392,7 @@ async def _track_user_joined_room(self, room_id: str, user_id: str) -> None:
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
Expand Down
14 changes: 13 additions & 1 deletion synapse/storage/databases/main/appservice.py
Original file line number Diff line number Diff line change
Expand Up @@ -157,7 +157,19 @@ async def get_app_service_users_in_room(
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))
Expand Down
19 changes: 12 additions & 7 deletions synapse/storage/databases/main/roommember.py
Original file line number Diff line number Diff line change
Expand Up @@ -152,13 +152,18 @@ async def get_users_in_room(self, room_id: str) -> List[str]:
`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
Expand Down

0 comments on commit 99a623d

Please sign in to comment.