From d0e80f314093f9dd4a4e3f8d87cd082e7d630739 Mon Sep 17 00:00:00 2001 From: Yorick Peterse Date: Fri, 7 Apr 2017 17:36:24 +0200 Subject: Reschedule project authorizations in a migration This reschedules the calculation of project authorizations of all users. This ensures that all users have a consistent state, even those that are not actively using the system. --- .../reschedule-project-authorizations.yml | 4 +++ ...0407153331_reschedule_project_authorizations.rb | 41 ++++++++++++++++++++++ 2 files changed, 45 insertions(+) create mode 100644 changelogs/unreleased/reschedule-project-authorizations.yml create mode 100644 db/migrate/20170407153331_reschedule_project_authorizations.rb diff --git a/changelogs/unreleased/reschedule-project-authorizations.yml b/changelogs/unreleased/reschedule-project-authorizations.yml new file mode 100644 index 00000000000..bff25dfca5e --- /dev/null +++ b/changelogs/unreleased/reschedule-project-authorizations.yml @@ -0,0 +1,4 @@ +--- +title: Reschedule project authorizations in a migration +merge_request: +author: diff --git a/db/migrate/20170407153331_reschedule_project_authorizations.rb b/db/migrate/20170407153331_reschedule_project_authorizations.rb new file mode 100644 index 00000000000..12463442e5e --- /dev/null +++ b/db/migrate/20170407153331_reschedule_project_authorizations.rb @@ -0,0 +1,41 @@ +# See http://doc.gitlab.com/ce/development/migration_style_guide.html +# for more information on how to write migrations for GitLab. + +class RescheduleProjectAuthorizations < ActiveRecord::Migration + include Gitlab::Database::MigrationHelpers + + DOWNTIME = false + + disable_ddl_transaction! + + class User < ActiveRecord::Base + self.table_name = 'users' + end + + def up + offset = nil + batch = 5000 + start = Time.now + + loop do + relation = offset ? User.where('id > ?', offset) : User.all + user_ids = relation.limit(batch).reorder(id: :asc).pluck(:id) + + break if user_ids.empty? + + offset = user_ids.last + + # This will schedule each batch 10 minutes after the previous batch was + # scheduled. This smears out the load over time, instead of immediately + # scheduling a million jobs. + Sidekiq::Client.push_bulk( + 'queue' => 'authorized_projects', + 'args' => user_ids.map { |id| [id] }, + 'class' => 'AuthorizedProjectsWorker', + 'at' => start.to_i + ) + + start += 10.minutes + end + end +end -- cgit v1.2.1