From 2d8475934fe5b0bf612c8d4043dcf88e21bad738 Mon Sep 17 00:00:00 2001 From: Jason Robinson Date: Fri, 17 Jul 2026 16:55:01 +0300 Subject: [PATCH] Remove `get_targets_for_profile_updates` We now calculate the targets when persisting the updates. --- synapse/handlers/profile.py | 83 +++++------------------ synapse/storage/databases/main/profile.py | 9 +-- tests/handlers/test_profile.py | 3 - tests/handlers/test_sync.py | 1 - tests/rest/admin/test_user.py | 6 -- tests/rest/client/test_account.py | 2 - tests/rest/synapse/mas/test_users.py | 2 - tests/storage/test_main.py | 1 - tests/storage/test_profile.py | 4 -- 9 files changed, 20 insertions(+), 91 deletions(-) diff --git a/synapse/handlers/profile.py b/synapse/handlers/profile.py index 851c56c45b..fc85372ec4 100644 --- a/synapse/handlers/profile.py +++ b/synapse/handlers/profile.py @@ -120,42 +120,6 @@ class ProfileHandler: self._set_profile_field_client = ReplicationProfileSetField.make_client(self.hs) self._profile_updates_writer_instance = self.hs.config.worker.writers.events[0] - async def get_targets_for_profile_updates( - self, user_id: UserID - ) -> dict[str, set[str]]: - """ - Get targets for the profile updates stream. - - Collects the rooms and users that are in the same rooms, and thus would be - interested in profile changes of our user. This will always include the user - themselves, even if the user is not in any rooms. - - Args: - user_id: The user ID that is updating a profile - - Returns: - Dictionary containing two sets, one for `rooms`, one for `users` - """ - if not self._msc4429_enabled: - return { - "rooms": set(), - "users": set(), - } - - room_ids = await self.store.get_rooms_for_user(user_id.to_string()) - if not room_ids: - return { - "rooms": set(), - "users": {user_id.to_string()}, - } - - return { - "rooms": set(room_ids), - "users": await self.store.get_local_users_who_share_room_with_user( - user_id.to_string() - ), - } - async def get_profile(self, user_id: str, ignore_backoff: bool = True) -> JsonDict: """ Get a user's profile as a JSON dictionary. @@ -252,7 +216,6 @@ class ProfileHandler: target_user: UserID, requester: Requester, new_displayname: str, - profile_update_target_user_ids: set[str], by_admin: bool = False, propagate: bool = True, ) -> int | None: @@ -271,8 +234,6 @@ class ProfileHandler: target_user: the user whose displayname is to be changed. requester: The user attempting to make this change. new_displayname: The displayname to give this user. - profile_update_target_user_ids: User IDs to trigger profile updates stream - updates for. by_admin: Whether this change was made by an administrator. propagate: Whether this change also applies to the user's membership events. @@ -321,7 +282,6 @@ class ProfileHandler: target_user, ProfileFields.DISPLAYNAME, displayname_to_set, - profile_update_target_user_ids, ) profile = await self.store.get_profileinfo(target_user) @@ -378,7 +338,6 @@ class ProfileHandler: target_user: UserID, requester: Requester, new_avatar_url: str, - profile_update_target_user_ids: set[str], by_admin: bool = False, propagate: bool = True, ) -> int | None: @@ -397,8 +356,6 @@ class ProfileHandler: target_user: the user whose avatar URL is to be changed. requester: The user attempting to make this change. new_avatar_url: The avatar URL to give this user. - profile_update_target_user_ids: User IDs to trigger profile update stream - updates for. by_admin: Whether this change was made by an administrator. propagate: Whether this change also applies to the user's membership events. @@ -445,7 +402,6 @@ class ProfileHandler: target_user, ProfileFields.AVATAR_URL, avatar_url_to_set, - profile_update_target_user_ids, ) profile = await self.store.get_profileinfo(target_user) @@ -709,8 +665,6 @@ class ProfileHandler: propagate: bool = True, ) -> None: """Wrapper function for setting any profile field for a user.""" - profile_update_targets = await self.get_targets_for_profile_updates(target_user) - if field_name == ProfileFields.DISPLAYNAME: if not isinstance(new_value, str): raise SynapseError( @@ -722,7 +676,6 @@ class ProfileHandler: new_displayname=new_value, by_admin=by_admin, propagate=propagate, - profile_update_target_user_ids=profile_update_targets["users"], ) elif field_name == ProfileFields.AVATAR_URL: if not isinstance(new_value, str): @@ -735,7 +688,6 @@ class ProfileHandler: new_avatar_url=new_value, by_admin=by_admin, propagate=propagate, - profile_update_target_user_ids=profile_update_targets["users"], ) else: stream_id = await self.set_profile_field( @@ -744,15 +696,16 @@ class ProfileHandler: field_name=field_name, new_value=new_value, by_admin=by_admin, - profile_update_target_user_ids=profile_update_targets["users"], ) - if stream_id is not None and profile_update_targets["rooms"]: - self._notifier.on_new_event( - StreamKeyType.PROFILE_UPDATES, - stream_id, - rooms=profile_update_targets["rooms"], - ) + if stream_id is not None: + room_ids = await self.store.get_rooms_for_user(target_user.to_string()) + if room_ids: + self._notifier.on_new_event( + StreamKeyType.PROFILE_UPDATES, + stream_id, + rooms=room_ids, + ) async def set_profile_field( self, @@ -761,7 +714,6 @@ class ProfileHandler: requester: Requester, field_name: str, new_value: JsonValue | dict[str, JsonValue], - profile_update_target_user_ids: set[str], by_admin: bool = False, ) -> int | None: """Set a new profile field for a user. @@ -778,8 +730,6 @@ class ProfileHandler: requester: The user attempting to make this change. field_name: The name of the profile field to update. new_value: The new field value for this user. - profile_update_target_user_ids: User ID's to trigger profile update stream - updates for. by_admin: Whether this change was made by an administrator. """ if not self.hs.is_mine(target_user): @@ -792,7 +742,6 @@ class ProfileHandler: target_user, field_name, new_value, - profile_update_target_user_ids, ) # Custom fields do not propagate into the user directory *or* rooms. @@ -872,9 +821,9 @@ class ProfileHandler: if not by_admin and target_user != requester.user: raise AuthError(400, "Cannot set another user's profile") - profile_update_targets = await self.get_targets_for_profile_updates(target_user) stream_id = await self.store.delete_profile_field( - target_user, field_name, profile_update_targets["users"] + target_user, + field_name, ) # Custom fields do not propagate into the user directory *or* rooms. @@ -884,11 +833,13 @@ class ProfileHandler: ) if stream_id: - self._notifier.on_new_event( - StreamKeyType.PROFILE_UPDATES, - stream_id, - rooms=profile_update_targets["rooms"], - ) + room_ids = await self.store.get_rooms_for_user(target_user.to_string()) + if room_ids: + self._notifier.on_new_event( + StreamKeyType.PROFILE_UPDATES, + stream_id, + rooms=room_ids, + ) async def on_profile_query(self, args: JsonDict) -> JsonDict: """Handles federation profile query requests.""" diff --git a/synapse/storage/databases/main/profile.py b/synapse/storage/databases/main/profile.py index f9f8d4c66b..3514ee71cc 100644 --- a/synapse/storage/databases/main/profile.py +++ b/synapse/storage/databases/main/profile.py @@ -670,7 +670,6 @@ class ProfileWorkerStore(SQLBaseStore): user_id: UserID, field_name: str, new_value: JsonValue | dict[str, JsonValue], - target_users: set[str], ) -> int | None: """ Wrapper function to set a profile field value and write to the profile @@ -681,7 +680,6 @@ class ProfileWorkerStore(SQLBaseStore): user_id: The user to set the profile field for field_name: The field to set the value for new_value: New value for the profile field - target_users: Users to trigger a profile update stream row for Returns: The profile updates stream ID that was created in this transaction @@ -942,7 +940,6 @@ class ProfileWorkerStore(SQLBaseStore): user_id: UserID, field_name: str, new_value: JsonValue | dict[str, JsonValue], - target_users: set[str], ) -> int | None: """ Set a custom profile field for a user. @@ -951,7 +948,6 @@ class ProfileWorkerStore(SQLBaseStore): user_id: The user's ID. field_name: The name of the custom profile field. new_value: The value of the custom profile field. - target_users: Set of users to trigger profile updates for. """ return await self.db_pool.runInteraction( "set_profile_field", @@ -959,11 +955,12 @@ class ProfileWorkerStore(SQLBaseStore): user_id, field_name, new_value, - target_users, ) async def delete_profile_field( - self, user_id: UserID, field_name: str, target_users: set[str] + self, + user_id: UserID, + field_name: str, ) -> int | None: """ Remove a custom profile field for a user. diff --git a/tests/handlers/test_profile.py b/tests/handlers/test_profile.py index a2cbe230b4..51e7e6d68c 100644 --- a/tests/handlers/test_profile.py +++ b/tests/handlers/test_profile.py @@ -954,7 +954,6 @@ class ProfileTestCase(unittest.HomeserverTestCase): user_id=self.frank, field_name=ProfileFields.DISPLAYNAME, new_value="Frank", - target_users=set(), ) ) @@ -1042,7 +1041,6 @@ class ProfileTestCase(unittest.HomeserverTestCase): user_id=self.frank, field_name=ProfileFields.DISPLAYNAME, new_value=None, - target_users=set(), ) ) self.get_success( @@ -1050,7 +1048,6 @@ class ProfileTestCase(unittest.HomeserverTestCase): user_id=self.frank, field_name=ProfileFields.AVATAR_URL, new_value="http://my.server/me.png", - target_users=set(), ) ) diff --git a/tests/handlers/test_sync.py b/tests/handlers/test_sync.py index 7deea142e2..ef26d1a515 100644 --- a/tests/handlers/test_sync.py +++ b/tests/handlers/test_sync.py @@ -1180,7 +1180,6 @@ class SyncProfileUpdatesTestCase(tests.unittest.HomeserverTestCase): user_id=UserID.from_string(self.user), field_name="m.status", new_value={"text": "Swimming in the Great Lakes!", "emoji": "🏊"}, - target_users=set(), ) ) self.helper.join( diff --git a/tests/rest/admin/test_user.py b/tests/rest/admin/test_user.py index 14be9389ab..e2e133a85e 100644 --- a/tests/rest/admin/test_user.py +++ b/tests/rest/admin/test_user.py @@ -948,7 +948,6 @@ class UsersListTestCase(unittest.HomeserverTestCase): user_id=UserID.from_string("@user1:test"), field_name=ProfileFields.AVATAR_URL, new_value="mxc://url3", - target_users=set(), ) ) self.get_success( @@ -956,7 +955,6 @@ class UsersListTestCase(unittest.HomeserverTestCase): user_id=UserID.from_string("@user2:test"), field_name=ProfileFields.AVATAR_URL, new_value="mxc://url2", - target_users=set(), ) ) self.get_success( @@ -964,7 +962,6 @@ class UsersListTestCase(unittest.HomeserverTestCase): user_id=UserID.from_string("@admin:test"), field_name=ProfileFields.AVATAR_URL, new_value="mxc://url1", - target_users=set(), ) ) @@ -1560,7 +1557,6 @@ class DeactivateAccountTestCase(unittest.HomeserverTestCase): user_id=UserID.from_string("@user:test"), field_name=ProfileFields.AVATAR_URL, new_value="mxc://servername/mediaid", - target_users=set(), ) ) self.get_success( @@ -1696,7 +1692,6 @@ class DeactivateAccountTestCase(unittest.HomeserverTestCase): user_id=UserID.from_string("@user:test"), field_name=ProfileFields.AVATAR_URL, new_value="", - target_users=set(), ) ) @@ -2780,7 +2775,6 @@ class UserRestTestCase(unittest.HomeserverTestCase): user_id=UserID.from_string("@user:test"), field_name=ProfileFields.AVATAR_URL, new_value="mxc://servername/mediaid", - target_users=set(), ) ) self.get_success( diff --git a/tests/rest/client/test_account.py b/tests/rest/client/test_account.py index d92bddc825..8ffac644b6 100644 --- a/tests/rest/client/test_account.py +++ b/tests/rest/client/test_account.py @@ -589,7 +589,6 @@ class DeactivateTestCase(unittest.HomeserverTestCase): user_id=user_id, field_name=ProfileFields.DISPLAYNAME, new_value="Kermit the Frog", - target_users=set(), ) ) self.get_success( @@ -597,7 +596,6 @@ class DeactivateTestCase(unittest.HomeserverTestCase): user_id=user_id, field_name=ProfileFields.AVATAR_URL, new_value="http://test/Kermit.jpg", - target_users=set(), ) ) diff --git a/tests/rest/synapse/mas/test_users.py b/tests/rest/synapse/mas/test_users.py index be6ff52fcc..9804f0195d 100644 --- a/tests/rest/synapse/mas/test_users.py +++ b/tests/rest/synapse/mas/test_users.py @@ -59,7 +59,6 @@ class MasQueryUserResource(BaseTestCase): user_id=alice, field_name=ProfileFields.AVATAR_URL, new_value="mxc://example.com/avatar", - target_users=set(), ) ) @@ -737,7 +736,6 @@ class MasDeleteUserResource(BaseTestCase): user_id=alice, field_name="io.element.example", new_value="hello", - target_users=set(), ) ) diff --git a/tests/storage/test_main.py b/tests/storage/test_main.py index 235e4ed678..dc98876930 100644 --- a/tests/storage/test_main.py +++ b/tests/storage/test_main.py @@ -41,7 +41,6 @@ class DataStoreTestCase(unittest.HomeserverTestCase): user_id=self.user, field_name=ProfileFields.DISPLAYNAME, new_value=self.displayname, - target_users=set(), ) ) diff --git a/tests/storage/test_profile.py b/tests/storage/test_profile.py index c099841267..b65af28962 100644 --- a/tests/storage/test_profile.py +++ b/tests/storage/test_profile.py @@ -45,7 +45,6 @@ class ProfileStoreTestCase(unittest.HomeserverTestCase): user_id=self.u_frank, field_name=ProfileFields.DISPLAYNAME, new_value="Frank", - target_users=set(), ) ) @@ -60,7 +59,6 @@ class ProfileStoreTestCase(unittest.HomeserverTestCase): user_id=self.u_frank, field_name=ProfileFields.DISPLAYNAME, new_value=None, - target_users=set(), ) ) @@ -76,7 +74,6 @@ class ProfileStoreTestCase(unittest.HomeserverTestCase): user_id=self.u_frank, field_name=ProfileFields.AVATAR_URL, new_value="http://my.site/here", - target_users=set(), ) ) @@ -91,7 +88,6 @@ class ProfileStoreTestCase(unittest.HomeserverTestCase): user_id=self.u_frank, field_name=ProfileFields.AVATAR_URL, new_value=None, - target_users=set(), ) )