Commit 6a915d6f authored by Toon Claes's avatar Toon Claes

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.
parent 8b9cd3c0
......@@ -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
......
---
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) }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment