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.
This commit is contained in:
Natalie Tay 2024-04-25 20:58:34 +08:00 committed by GitHub
parent c62d3610c6
commit 00a9369ca2
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
5 changed files with 48 additions and 3 deletions

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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