PERF: Update all user_histories with one query in UserDestroyer (#16717)
7a284164
previously switched the UserDestroyer to use find_each when iterating over UserHistory records. Unfortunately, since this logic is wrapped in a transaction, this didn't actually solve the memory usage problem. ActiveRecord maintains references to all modified models within a transaction.
This commit updates the logic to use a single SQL query, rather than updating models one-by-one
This commit is contained in:
parent
d90065e0ef
commit
67b23c0e22
|
@ -47,13 +47,10 @@ class UserDestroyer
|
|||
# Add info about the user to staff action logs
|
||||
UserHistory.staff_action_records(
|
||||
Discourse.system_user, acting_user: user.username
|
||||
).unscope(:order).find_each do |log|
|
||||
log.details ||= ''
|
||||
log.details = (log.details.split("\n") +
|
||||
["user_id: #{user.id}", "username: #{user.username}"]
|
||||
).join("\n")
|
||||
log.save!
|
||||
end
|
||||
).update_all([
|
||||
"details = CONCAT(details, ?)",
|
||||
"\nuser_id: #{user.id}\nusername: #{user.username}"
|
||||
])
|
||||
|
||||
# keep track of emails used
|
||||
user_emails = user.user_emails.pluck(:email)
|
||||
|
|
|
@ -442,19 +442,28 @@ describe UserDestroyer do
|
|||
logger.log_site_setting_change(
|
||||
'site_description',
|
||||
'Our friendly community',
|
||||
'My favourite community'
|
||||
'My favourite community',
|
||||
)
|
||||
logger.log_site_setting_change(
|
||||
'site_description',
|
||||
'Our friendly community',
|
||||
'My favourite community',
|
||||
details: "existing details"
|
||||
)
|
||||
end
|
||||
|
||||
it "should keep the staff action log and add the username" do
|
||||
username = user.username
|
||||
log = UserHistory.staff_action_records(
|
||||
ids = UserHistory.staff_action_records(
|
||||
Discourse.system_user,
|
||||
acting_user: username
|
||||
).to_a[0]
|
||||
).map(&:id)
|
||||
UserDestroyer.new(admin).destroy(user, delete_posts: true)
|
||||
log.reload
|
||||
expect(log.details).to include(username)
|
||||
details = UserHistory.where(id: ids).map(&:details)
|
||||
expect(details).to contain_exactly(
|
||||
"\nuser_id: #{user.id}\nusername: #{username}",
|
||||
"existing details\nuser_id: #{user.id}\nusername: #{username}"
|
||||
)
|
||||
end
|
||||
end
|
||||
|
||||
|
|
Loading…
Reference in New Issue