PERF: optimize chat user membership cleanup when removing a single user (#29833)

This optimizes a hot path when users are being removed from one or more groups since we use the `on(:user_removed_from_group)` event to call the `Chat::AutoLeaveChannels` with a `user_id` parameter. In such case, we don't need to clear the membership of all users, just that one user.

DEBUG: Also added a "-- event = <event>" comment on top of the SQL queries used by the "AutoLeaveChannels" so they show up in the logs and hopefully facilitate any performance issues that might arise in the future.
This commit is contained in:
Régis Hanol
2024-11-20 09:21:02 +01:00
committed by GitHub
parent eb41a07afb
commit 7cf28fec7b
3 changed files with 29 additions and 10 deletions

View File

@ -17,6 +17,8 @@ module Chat
attribute :group_id, :integer
attribute :channel_id, :integer
attribute :category_id, :integer
validates :event, presence: true
end
step :remove_memberships
@ -34,6 +36,7 @@ module Chat
if !group_ids.include?(Group::AUTO_GROUPS[:everyone])
sql = <<~SQL
-- event = #{params.event}
DELETE FROM user_chat_channel_memberships uccm
WHERE NOT EXISTS (
SELECT 1
@ -41,6 +44,7 @@ module Chat
WHERE gu.user_id = uccm.user_id
AND gu.group_id IN (:group_ids)
)
#{params.user_id ? "AND uccm.user_id = #{params.user_id}" : ""}
RETURNING chat_channel_id, user_id
SQL
@ -54,6 +58,7 @@ module Chat
category_sql = params.category_id ? "AND c.id = #{params.category_id}" : ""
sql = <<~SQL
-- event = #{params.event}
WITH valid_permissions AS (
SELECT gu.user_id, cg.category_id
FROM group_users gu