2018-11-09 13:39:43 -05:00
|
|
|
# frozen_string_literal: true
|
|
|
|
|
2018-06-07 11:40:44 -04:00
|
|
|
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
|
|
|
|
#
|
2018-12-22 08:54:33 -05:00
|
|
|
# @param [Integer] start first project id for the range
|
|
|
|
# @param [Integer] finish last project id for the range
|
2019-01-16 20:53:50 -05:00
|
|
|
def bulk_schedule(start:, finish:)
|
|
|
|
::HashedStorage::MigratorWorker.perform_async(start, finish)
|
2018-06-07 11:40:44 -04:00
|
|
|
end
|
|
|
|
|
|
|
|
# Start migration of projects from specified range
|
|
|
|
#
|
2019-01-16 20:53:50 -05:00
|
|
|
# Flagging a project to be migrated is a synchronous action
|
2018-06-07 11:40:44 -04:00
|
|
|
# but the migration runs through async jobs
|
|
|
|
#
|
2018-12-22 08:54:33 -05:00
|
|
|
# @param [Integer] start first project id for the range
|
|
|
|
# @param [Integer] finish last project id for the range
|
2018-08-27 11:31:01 -04:00
|
|
|
# rubocop: disable CodeReuse/ActiveRecord
|
2019-01-16 20:53:50 -05:00
|
|
|
def bulk_migrate(start:, finish:)
|
2018-06-07 11:40:44 -04:00
|
|
|
projects = build_relation(start, finish)
|
|
|
|
|
|
|
|
projects.with_route.find_each(batch_size: BATCH_SIZE) do |project|
|
2019-01-16 20:53:50 -05:00
|
|
|
migrate(project)
|
2018-06-07 11:40:44 -04:00
|
|
|
end
|
|
|
|
end
|
2018-08-27 11:31:01 -04:00
|
|
|
# rubocop: enable CodeReuse/ActiveRecord
|
2018-06-07 11:40:44 -04:00
|
|
|
|
2019-01-16 20:53:50 -05:00
|
|
|
# Flag a project to be migrated to Hashed Storage
|
2018-06-07 11:40:44 -04:00
|
|
|
#
|
2018-12-22 08:54:33 -05:00
|
|
|
# @param [Project] project that will be migrated
|
2018-06-07 11:40:44 -04:00
|
|
|
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
|
|
|
|
|
2019-01-16 20:57:35 -05:00
|
|
|
# Flag a project to be rolled-back to Legacy Storage
|
|
|
|
#
|
|
|
|
# @param [Project] project that will be rolled-back
|
2018-12-22 08:54:33 -05:00
|
|
|
def rollback(project)
|
2019-01-16 20:57:35 -05:00
|
|
|
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}")
|
2018-12-22 08:54:33 -05:00
|
|
|
end
|
|
|
|
|
2018-06-07 11:40:44 -04:00
|
|
|
private
|
|
|
|
|
2018-08-27 11:31:01 -04:00
|
|
|
# rubocop: disable CodeReuse/ActiveRecord
|
2018-06-07 11:40:44 -04:00
|
|
|
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
|
2018-08-27 11:31:01 -04:00
|
|
|
# rubocop: enable CodeReuse/ActiveRecord
|
2018-06-07 11:40:44 -04:00
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|