Commit 3e152e42 authored by Imre Farkas's avatar Imre Farkas

Log details of authorized projects refresh

Details including the source from where the refresh was triggered will
help to determine if specialized workers do the updates correctly, and
if we still need to run low urgency AuthorizedProjectsWorker.
parent b1394f1e
...@@ -960,8 +960,8 @@ class User < ApplicationRecord ...@@ -960,8 +960,8 @@ class User < ApplicationRecord
end end
# rubocop: disable CodeReuse/ServiceClass # rubocop: disable CodeReuse/ServiceClass
def refresh_authorized_projects def refresh_authorized_projects(source: nil)
Users::RefreshAuthorizedProjectsService.new(self).execute Users::RefreshAuthorizedProjectsService.new(self, source: source).execute
end end
# rubocop: enable CodeReuse/ServiceClass # rubocop: enable CodeReuse/ServiceClass
......
...@@ -9,7 +9,7 @@ module AuthorizedProjectUpdate ...@@ -9,7 +9,7 @@ module AuthorizedProjectUpdate
def execute def execute
User.where(id: start_user_id..end_user_id).select(:id).find_each do |user| # rubocop: disable CodeReuse/ActiveRecord User.where(id: start_user_id..end_user_id).select(:id).find_each do |user| # rubocop: disable CodeReuse/ActiveRecord
Users::RefreshAuthorizedProjectsService.new(user).execute Users::RefreshAuthorizedProjectsService.new(user, source: self.class.name).execute
end end
end end
......
...@@ -14,13 +14,14 @@ module Users ...@@ -14,13 +14,14 @@ module Users
# service = Users::RefreshAuthorizedProjectsService.new(some_user) # service = Users::RefreshAuthorizedProjectsService.new(some_user)
# service.execute # service.execute
class RefreshAuthorizedProjectsService class RefreshAuthorizedProjectsService
attr_reader :user attr_reader :user, :source
LEASE_TIMEOUT = 1.minute.to_i LEASE_TIMEOUT = 1.minute.to_i
# user - The User for which to refresh the authorized projects. # user - The User for which to refresh the authorized projects.
def initialize(user, incorrect_auth_found_callback: nil, missing_auth_found_callback: nil) def initialize(user, source: nil, incorrect_auth_found_callback: nil, missing_auth_found_callback: nil)
@user = user @user = user
@source = source
@incorrect_auth_found_callback = incorrect_auth_found_callback @incorrect_auth_found_callback = incorrect_auth_found_callback
@missing_auth_found_callback = missing_auth_found_callback @missing_auth_found_callback = missing_auth_found_callback
...@@ -91,6 +92,8 @@ module Users ...@@ -91,6 +92,8 @@ module Users
# remove - The IDs of the authorization rows to remove. # remove - The IDs of the authorization rows to remove.
# add - Rows to insert in the form `[user id, project id, access level]` # add - Rows to insert in the form `[user id, project id, access level]`
def update_authorizations(remove = [], add = []) def update_authorizations(remove = [], add = [])
log_refresh_details(remove.length, add.length)
User.transaction do User.transaction do
user.remove_project_authorizations(remove) unless remove.empty? user.remove_project_authorizations(remove) unless remove.empty?
ProjectAuthorization.insert_authorizations(add) unless add.empty? ProjectAuthorization.insert_authorizations(add) unless add.empty?
...@@ -101,6 +104,13 @@ module Users ...@@ -101,6 +104,13 @@ module Users
user.reset user.reset
end end
def log_refresh_details(rows_deleted, rows_added)
Gitlab::AppJsonLogger.info(event: 'authorized_projects_refresh',
'authorized_projects_refresh.source': source,
'authorized_projects_refresh.rows_deleted': rows_deleted,
'authorized_projects_refresh.rows_added': rows_added)
end
def fresh_access_levels_per_project def fresh_access_levels_per_project
fresh_authorizations.each_with_object({}) do |row, hash| fresh_authorizations.each_with_object({}) do |row, hash|
hash[row.project_id] = row.access_level hash[row.project_id] = row.access_level
......
...@@ -25,7 +25,7 @@ class AuthorizedProjectsWorker ...@@ -25,7 +25,7 @@ class AuthorizedProjectsWorker
def perform(user_id) def perform(user_id)
user = User.find_by(id: user_id) user = User.find_by(id: user_id)
user&.refresh_authorized_projects user&.refresh_authorized_projects(source: self.class.name)
end end
# rubocop: enable CodeReuse/ActiveRecord # rubocop: enable CodeReuse/ActiveRecord
end end
...@@ -9,7 +9,7 @@ RSpec.describe AuthorizedProjectUpdate::RecalculateForUserRangeService do ...@@ -9,7 +9,7 @@ RSpec.describe AuthorizedProjectUpdate::RecalculateForUserRangeService do
it 'calls Users::RefreshAuthorizedProjectsService' do it 'calls Users::RefreshAuthorizedProjectsService' do
users.each do |user| users.each do |user|
expect(Users::RefreshAuthorizedProjectsService).to( expect(Users::RefreshAuthorizedProjectsService).to(
receive(:new).with(user).and_call_original) receive(:new).with(user, source: described_class.name).and_call_original)
end end
range = users.map(&:id).minmax range = users.map(&:id).minmax
......
...@@ -143,6 +143,21 @@ RSpec.describe Users::RefreshAuthorizedProjectsService do ...@@ -143,6 +143,21 @@ RSpec.describe Users::RefreshAuthorizedProjectsService do
expect(authorizations[0].project_id).to eq(project.id) expect(authorizations[0].project_id).to eq(project.id)
expect(authorizations[0].access_level).to eq(Gitlab::Access::MAINTAINER) expect(authorizations[0].access_level).to eq(Gitlab::Access::MAINTAINER)
end end
it 'logs the details of the refresh' do
source = :foo
service = described_class.new(user, source: source)
user.project_authorizations.delete_all
expect(Gitlab::AppJsonLogger).to(
receive(:info)
.with(event: 'authorized_projects_refresh',
'authorized_projects_refresh.source': source,
'authorized_projects_refresh.rows_deleted': 0,
'authorized_projects_refresh.rows_added': 1))
service.update_authorizations([], [[user.id, project.id, Gitlab::Access::MAINTAINER]])
end
end end
describe '#fresh_access_levels_per_project' do describe '#fresh_access_levels_per_project' do
......
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