debian-mirror-gitlab/lib/gitlab/background_migration/populate_projects_star_count.rb
2023-01-13 15:02:22 +05:30

58 lines
1.6 KiB
Ruby

# frozen_string_literal: true
module Gitlab
module BackgroundMigration
# The class to populates the star counter of projects
class PopulateProjectsStarCount < BatchedMigrationJob
MAX_UPDATE_RETRIES = 3
operation_name :update_all
def perform
each_sub_batch do |sub_batch|
update_with_retry(sub_batch)
end
end
private
# rubocop:disable Database/RescueQueryCanceled
# rubocop:disable Database/RescueStatementTimeout
def update_with_retry(sub_batch)
update_attempt = 1
begin
update_batch(sub_batch)
rescue ActiveRecord::StatementTimeout, ActiveRecord::QueryCanceled => e
update_attempt += 1
if update_attempt <= MAX_UPDATE_RETRIES
sleep(5)
retry
end
raise e
end
end
# rubocop:enable Database/RescueQueryCanceled
# rubocop:enable Database/RescueStatementTimeout
def update_batch(sub_batch)
ApplicationRecord.connection.execute <<~SQL
WITH batched_relation AS #{Gitlab::Database::AsWithMaterialized.materialized_if_supported} (#{sub_batch.select(:id).to_sql})
UPDATE projects
SET star_count = (
SELECT COUNT(*)
FROM users_star_projects
INNER JOIN users
ON users_star_projects.user_id = users.id
WHERE users_star_projects.project_id = batched_relation.id
AND users.state = 'active'
)
FROM batched_relation
WHERE projects.id = batched_relation.id
SQL
end
end
end
end