From 9deebfb5b30fa13356851272cb8a89a85345cc01 Mon Sep 17 00:00:00 2001 From: Jason Robinson Date: Fri, 17 Jul 2026 16:41:31 +0300 Subject: [PATCH] Remove writing to the profile updates stream in `delete_profile_upon_deactivation` We'll anyway have "left room" actions generated for the user for everyone who is interested, as the user parter pushes them out of the room. Thus we would be doing unnecessary extra work here. --- synapse/handlers/profile.py | 37 +++-------------------- synapse/storage/databases/main/profile.py | 22 ++------------ 2 files changed, 8 insertions(+), 51 deletions(-) diff --git a/synapse/handlers/profile.py b/synapse/handlers/profile.py index 28c8e63fe9..851c56c45b 100644 --- a/synapse/handlers/profile.py +++ b/synapse/handlers/profile.py @@ -512,6 +512,9 @@ class ProfileHandler: **leave** the room on the user's behalf, so there's no point sending new join events into rooms to propagate the profile deletion. See the `users_pending_deactivation` table and the associated user parter loop. + + Profile update streams are NOT updated in any way; this happens when the + event persister processes the room leave events triggered elsewhere as above. """ if not self.hs.is_mine(target_user): raise SynapseError(400, "User is not hosted on this homeserver") @@ -524,40 +527,10 @@ class ProfileHandler: # have it. raise AuthError(400, "Cannot remove another user's profile") - profile_updates: list[str] = [] - profile_update_targets: dict = {"rooms": set(), "users": set()} - - if self._msc4429_enabled: - current_profile = await self.store.get_profileinfo(target_user) - - if current_profile.display_name is not None: - profile_updates.append(ProfileFields.DISPLAYNAME) - if current_profile.avatar_url is not None: - profile_updates.append(ProfileFields.AVATAR_URL) - - custom_fields = await self.store.get_profile_fields(target_user) - for field_name in custom_fields.keys(): - profile_updates.append(field_name) - - if profile_updates: - profile_update_targets = await self.get_targets_for_profile_updates( - target_user - ) - # Discard ourselves as we're deactivating this account - profile_update_targets["users"].discard(target_user.to_string()) - - # Record the profile delete and update the profile updates stream - stream_id = await self.store.delete_profile( + # Record the profile delete + await self.store.delete_profile( user_id=target_user, - field_names=profile_updates, - target_users=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"], - ) await self._third_party_rules.on_profile_update( target_user.to_string(), diff --git a/synapse/storage/databases/main/profile.py b/synapse/storage/databases/main/profile.py index d6dc2d2ab6..f9f8d4c66b 100644 --- a/synapse/storage/databases/main/profile.py +++ b/synapse/storage/databases/main/profile.py @@ -1015,24 +1015,16 @@ class ProfileWorkerStore(SQLBaseStore): async def delete_profile( self, user_id: UserID, - field_names: list[str], - target_users: set[str], - ) -> int | None: + ) -> None: """ Deletes an entire user profile, including displayname, avatar_url and all custom fields. Used at user deactivation when erasure is requested. Args: user_id: User ID whose profile is going to be deleted. - field_names: List of profile fields the user had. - target_users: List of users who share rooms and are interested in - profile updates for this user. - - Returns: - Latest stream ID for the profile updates stream. """ - def _delete_profile_txn(txn: LoggingTransaction) -> int | None: + def _delete_profile_txn(txn: LoggingTransaction) -> None: # Delete the profile txn.execute( """ @@ -1041,16 +1033,8 @@ class ProfileWorkerStore(SQLBaseStore): """, (user_id.to_string(),), ) - # Update the profile updates stream - stream_id = self.record_profile_updates_txn( - txn=txn, - user_id=user_id, - action=ProfileUpdateAction.UPDATE, - field_names=field_names, - ) - return stream_id - return await self.db_pool.runInteraction( + await self.db_pool.runInteraction( "delete_profile", _delete_profile_txn, )