From 00a9369ca2ef2f0cd999967c3b69b8fbc4c0593b Mon Sep 17 00:00:00 2001 From: Natalie Tay Date: Thu, 25 Apr 2024 20:58:34 +0800 Subject: [PATCH] FIX: Move user reindexing into a job (#26753) In a large forum with millions of users and millions of user_fields updating the list of dropdown user field options will result in a 502 now due to the large number of fields. This commit moves the indexing into a job. --- .../regular/index_user_fields_for_search.rb | 10 ++++++++++ app/models/user_field.rb | 4 +--- .../user_custom_field_fabricator.rb | 7 +++++++ .../jobs/index_user_fields_for_search_spec.rb | 20 +++++++++++++++++++ spec/models/user_field_spec.rb | 10 ++++++++++ 5 files changed, 48 insertions(+), 3 deletions(-) create mode 100644 app/jobs/regular/index_user_fields_for_search.rb create mode 100644 spec/fabricators/user_custom_field_fabricator.rb create mode 100644 spec/jobs/index_user_fields_for_search_spec.rb diff --git a/app/jobs/regular/index_user_fields_for_search.rb b/app/jobs/regular/index_user_fields_for_search.rb new file mode 100644 index 00000000000..1a2957dbe1c --- /dev/null +++ b/app/jobs/regular/index_user_fields_for_search.rb @@ -0,0 +1,10 @@ +# frozen_string_literal: true + +class Jobs::IndexUserFieldsForSearch < Jobs::Base + def execute(args) + user_field_id = args[:user_field_id] + SearchIndexer.queue_users_reindex( + UserCustomField.where(name: "user_field_#{user_field_id}").pluck(:user_id), + ) + end +end diff --git a/app/models/user_field.rb b/app/models/user_field.rb index 3d492ab28ed..338d757f4b6 100644 --- a/app/models/user_field.rb +++ b/app/models/user_field.rb @@ -20,9 +20,7 @@ class UserField < ActiveRecord::Base end def queue_index_search - SearchIndexer.queue_users_reindex( - UserCustomField.where(name: "user_field_#{self.id}").pluck(:user_id), - ) + Jobs.enqueue(:index_user_fields_for_search, user_field_id: self.id) end private diff --git a/spec/fabricators/user_custom_field_fabricator.rb b/spec/fabricators/user_custom_field_fabricator.rb new file mode 100644 index 00000000000..abcb8910922 --- /dev/null +++ b/spec/fabricators/user_custom_field_fabricator.rb @@ -0,0 +1,7 @@ +# frozen_string_literal: true + +Fabricator(:user_custom_field) do + user + name { Fabricate(:user_field).id } + value { sequence(:value) { |n| "value#{n}" } } +end diff --git a/spec/jobs/index_user_fields_for_search_spec.rb b/spec/jobs/index_user_fields_for_search_spec.rb new file mode 100644 index 00000000000..42f6392f760 --- /dev/null +++ b/spec/jobs/index_user_fields_for_search_spec.rb @@ -0,0 +1,20 @@ +# frozen_string_literal: true + +RSpec.describe Jobs::IndexUserFieldsForSearch do + subject(:job) { described_class.new } + + before do + SearchIndexer.enable + Jobs.run_immediately! + end + + it "triggers a reindex when executed" do + user = Fabricate(:user) + user_field = Fabricate(:user_field) + Fabricate(:user_custom_field, user: user, name: "user_field_#{user_field.id}") + + job.execute(user_field_id: user_field.id) + + expect(user.reload.user_search_data.version).to eq(SearchIndexer::REINDEX_VERSION) + end +end diff --git a/spec/models/user_field_spec.rb b/spec/models/user_field_spec.rb index cf056e5f0b0..9f6a5f80e97 100644 --- a/spec/models/user_field_spec.rb +++ b/spec/models/user_field_spec.rb @@ -30,4 +30,14 @@ RSpec.describe UserField do expect(user_field.description).to eq(link) end + + it "enqueues index user fields job on save" do + user_field = Fabricate(:user_field) + + user_field.update!(description: "tomtom") + + expect( + job_enqueued?(job: Jobs::IndexUserFieldsForSearch, args: { user_field_id: user_field.id }), + ).to eq(true) + end end