mirror of
https://github.com/discourse/discourse.git
synced 2025-02-25 18:55:32 -06:00
PERF: Update Group#user_count counter cache outside DB transaction (#19256)
While load testing our user creation code path in production, we identified that executing the DB statement to update the `Group#user_count` column within a transaction is creating a bottleneck for us. This is because the creation of a user and addition of the user to the relevant groups are done in a transaction. When we execute the DB statement to update `Group#user_count` for the relevant group, a row level lock is held until the transaction completes. This row level lock acts like a global lock when the server is creating users that will be added to the same group in quick succession. Instead of updating the counter cache within a transaction which the default ActiveRecord `counter_cache` option does, we simply update the counter cache outside of the committing transaction. Co-authored-by: Rafael dos Santos Silva <xfalcox@gmail.com> Co-authored-by: Rafael dos Santos Silva <xfalcox@gmail.com>
This commit is contained in:
committed by
GitHub
parent
9f022112e3
commit
7c321d3aad
@@ -1,7 +1,7 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
class GroupUser < ActiveRecord::Base
|
||||
belongs_to :group, counter_cache: "user_count"
|
||||
belongs_to :group
|
||||
belongs_to :user
|
||||
|
||||
after_save :update_title
|
||||
@@ -15,6 +15,9 @@ class GroupUser < ActiveRecord::Base
|
||||
after_save :set_category_notifications
|
||||
after_save :set_tag_notifications
|
||||
|
||||
after_commit :increase_group_user_count, on: [:create]
|
||||
after_commit :decrease_group_user_count, on: [:destroy]
|
||||
|
||||
def self.notification_levels
|
||||
NotificationLevels.all
|
||||
end
|
||||
@@ -186,6 +189,14 @@ class GroupUser < ActiveRecord::Base
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def increase_group_user_count
|
||||
Group.increment_counter(:user_count, self.group_id)
|
||||
end
|
||||
|
||||
def decrease_group_user_count
|
||||
Group.decrement_counter(:user_count, self.group_id)
|
||||
end
|
||||
end
|
||||
|
||||
# == Schema Information
|
||||
|
||||
Reference in New Issue
Block a user