fc0ff92807
Rollback is done similar to Migration for the Hashed Storage. It also shares the same ExclusiveLease key to prevent both happening at the same time. All Hashed Storage related workers now share the same queue namespace which allows for assigning dedicated workers easily.
99 lines
3.5 KiB
Ruby
99 lines
3.5 KiB
Ruby
# frozen_string_literal: true
|
|
|
|
module Gitlab
|
|
module HashedStorage
|
|
# Hashed Storage Migrator
|
|
#
|
|
# This is responsible for scheduling and flagging projects
|
|
# to be migrated from Legacy to Hashed storage, either one by one or in bulk.
|
|
class Migrator
|
|
BATCH_SIZE = 100
|
|
|
|
# Schedule a range of projects to be bulk migrated with #bulk_migrate asynchronously
|
|
#
|
|
# @param [Integer] start first project id for the range
|
|
# @param [Integer] finish last project id for the range
|
|
def bulk_schedule_migration(start:, finish:)
|
|
::HashedStorage::MigratorWorker.perform_async(start, finish)
|
|
end
|
|
|
|
# Schedule a range of projects to be bulk rolledback with #bulk_rollback asynchronously
|
|
#
|
|
# @param [Integer] start first project id for the range
|
|
# @param [Integer] finish last project id for the range
|
|
def bulk_schedule_rollback(start:, finish:)
|
|
::HashedStorage::RollbackerWorker.perform_async(start, finish)
|
|
end
|
|
|
|
# Start migration of projects from specified range
|
|
#
|
|
# Flagging a project to be migrated is a synchronous action
|
|
# but the migration runs through async jobs
|
|
#
|
|
# @param [Integer] start first project id for the range
|
|
# @param [Integer] finish last project id for the range
|
|
# rubocop: disable CodeReuse/ActiveRecord
|
|
def bulk_migrate(start:, finish:)
|
|
projects = build_relation(start, finish)
|
|
|
|
projects.with_route.find_each(batch_size: BATCH_SIZE) do |project|
|
|
migrate(project)
|
|
end
|
|
end
|
|
# rubocop: enable CodeReuse/ActiveRecord
|
|
|
|
# Start rollback of projects from specified range
|
|
#
|
|
# Flagging a project to be rolled back is a synchronous action
|
|
# but the rollback runs through async jobs
|
|
#
|
|
# @param [Integer] start first project id for the range
|
|
# @param [Integer] finish last project id for the range
|
|
# rubocop: disable CodeReuse/ActiveRecord
|
|
def bulk_rollback(start:, finish:)
|
|
projects = build_relation(start, finish)
|
|
|
|
projects.with_route.find_each(batch_size: BATCH_SIZE) do |project|
|
|
rollback(project)
|
|
end
|
|
end
|
|
# rubocop: enable CodeReuse/ActiveRecord
|
|
|
|
# Flag a project to be migrated to Hashed Storage
|
|
#
|
|
# @param [Project] project that will be migrated
|
|
def migrate(project)
|
|
Rails.logger.info "Starting storage migration of #{project.full_path} (ID=#{project.id})..."
|
|
|
|
project.migrate_to_hashed_storage!
|
|
rescue => err
|
|
Rails.logger.error("#{err.message} migrating storage of #{project.full_path} (ID=#{project.id}), trace - #{err.backtrace}")
|
|
end
|
|
|
|
# Flag a project to be rolled-back to Legacy Storage
|
|
#
|
|
# @param [Project] project that will be rolled-back
|
|
def rollback(project)
|
|
Rails.logger.info "Starting storage rollback of #{project.full_path} (ID=#{project.id})..."
|
|
|
|
project.rollback_to_legacy_storage!
|
|
rescue => err
|
|
Rails.logger.error("#{err.message} rolling-back storage of #{project.full_path} (ID=#{project.id}), trace - #{err.backtrace}")
|
|
end
|
|
|
|
private
|
|
|
|
# rubocop: disable CodeReuse/ActiveRecord
|
|
def build_relation(start, finish)
|
|
relation = Project
|
|
table = Project.arel_table
|
|
|
|
relation = relation.where(table[:id].gteq(start)) if start
|
|
relation = relation.where(table[:id].lteq(finish)) if finish
|
|
|
|
relation
|
|
end
|
|
# rubocop: enable CodeReuse/ActiveRecord
|
|
end
|
|
end
|
|
end
|