Limit update_tracked_fields
to write to database once/hour
Every time a user logs in or out, the Trackable attributes are written to the database. This is causing a lot of load on the database, for data that isn't really critical. So to avoid the database being hammered, add a Gitlab::ExclusiveLease before writing trackable attributes to the database. This lease expires after an hour, so only when the attributes were written more than an hour ago, they can be written again. Otherwise they are ignored.
This commit is contained in:
parent
8b9cd3c072
commit
6a915d6f2d
3 changed files with 33 additions and 0 deletions
|
@ -40,6 +40,16 @@ class User < ActiveRecord::Base
|
|||
devise :lockable, :recoverable, :rememberable, :trackable,
|
||||
:validatable, :omniauthable, :confirmable, :registerable
|
||||
|
||||
# Limit trackable fields to update at most once every hour
|
||||
alias_method :devise_update_tracked_fields!, :update_tracked_fields!
|
||||
|
||||
def update_tracked_fields!(request)
|
||||
lease = Gitlab::ExclusiveLease.new("user_update_tracked_fields:#{id}", timeout: 1.hour.to_i)
|
||||
return unless lease.try_obtain
|
||||
|
||||
devise_update_tracked_fields!(request)
|
||||
end
|
||||
|
||||
attr_accessor :force_random_password
|
||||
|
||||
# Virtual attribute for authenticating by either username or email
|
||||
|
|
4
changelogs/unreleased/tc-cache-trackable-attributes.yml
Normal file
4
changelogs/unreleased/tc-cache-trackable-attributes.yml
Normal file
|
@ -0,0 +1,4 @@
|
|||
---
|
||||
title: "Limit User's trackable attributes, like `current_sign_in_at`, to update at most once/hour"
|
||||
merge_request: 11053
|
||||
author:
|
|
@ -344,6 +344,25 @@ describe User, models: true do
|
|||
end
|
||||
end
|
||||
|
||||
describe '#update_tracked_fields!', :redis do
|
||||
let(:request) { OpenStruct.new(remote_ip: "127.0.0.1") }
|
||||
let(:user) { create(:user) }
|
||||
|
||||
it 'writes trackable attributes' do
|
||||
expect do
|
||||
user.update_tracked_fields!(request)
|
||||
end.to change { user.reload.current_sign_in_at }
|
||||
end
|
||||
|
||||
it 'does not write trackable attributes when called a second time within the hour' do
|
||||
user.update_tracked_fields!(request)
|
||||
|
||||
expect do
|
||||
user.update_tracked_fields!(request)
|
||||
end.not_to change { user.current_sign_in_at }
|
||||
end
|
||||
end
|
||||
|
||||
shared_context 'user keys' do
|
||||
let(:user) { create(:user) }
|
||||
let!(:key) { create(:key, user: user) }
|
||||
|
|
Loading…
Reference in a new issue