From de79e5628ed132a791694b6f066c84007e638608 Mon Sep 17 00:00:00 2001 From: Alan Guo Xiang Tan Date: Fri, 16 Aug 2024 11:35:08 +0800 Subject: [PATCH] PERF: Reduce mem allocation of `Chat::AutoRemove::HandleCategoryUpdated` (#28393) This is a follow-up to 671f40ce07ebda14e4655cb85ce4794b859023f0 and ed11ee9d057160e5c1b0d1a86c9e94582d8fafd0. While the optimisations in the previous commits were sound, it did not resolve the memory bloat we were seeing. It turns out that we call `.blank?` on the model's result if the model has not been marked optional. The problem with this is that if the model returns an ActiveRecord relation, calling `.blank?` on the relation basically loads everything into memory. Therefore, this commit removes `users` as a model in the since it really isn't a model but just a relation. --- .../auto_remove/handle_category_updated.rb | 24 ++++++++----------- 1 file changed, 10 insertions(+), 14 deletions(-) diff --git a/plugins/chat/app/services/chat/auto_remove/handle_category_updated.rb b/plugins/chat/app/services/chat/auto_remove/handle_category_updated.rb index fff835bc986..030f2da38d9 100644 --- a/plugins/chat/app/services/chat/auto_remove/handle_category_updated.rb +++ b/plugins/chat/app/services/chat/auto_remove/handle_category_updated.rb @@ -19,7 +19,6 @@ module Chat policy :chat_enabled model :category model :category_channel_ids - model :users step :remove_users_without_channel_permission step :publish @@ -47,21 +46,18 @@ module Chat Chat::Channel.where(chatable: category).pluck(:id) end - def fetch_users(category_channel_ids:) - User - .real - .activated - .not_suspended - .not_staged - .joins(:user_chat_channel_memberships) - .where("user_chat_channel_memberships.chat_channel_id IN (?)", category_channel_ids) - .where("NOT admin AND NOT moderator") - end - - def remove_users_without_channel_permission(users:, category_channel_ids:) + def remove_users_without_channel_permission(category_channel_ids:) memberships_to_remove = Chat::Action::CalculateMembershipsForRemoval.call( - scoped_users_query: users, + scoped_users_query: + User + .real + .activated + .not_suspended + .not_staged + .joins(:user_chat_channel_memberships) + .where("user_chat_channel_memberships.chat_channel_id IN (?)", category_channel_ids) + .where("NOT admin AND NOT moderator"), channel_ids: category_channel_ids, )