Commit 5655d7cb authored by Stan Hu's avatar Stan Hu

Merge branch 'make_repository_moves_job_idempotent' into 'master'

Make ProjectUpdateRepositoryStorageWorker idempotent

See merge request gitlab-org/gitlab!35483
parents 7618cb15 d0d176c1
...@@ -14,7 +14,11 @@ module Projects ...@@ -14,7 +14,11 @@ module Projects
end end
def execute def execute
repository_storage_move.start! repository_storage_move.with_lock do
return ServiceResponse.success unless repository_storage_move.scheduled? # rubocop:disable Cop/AvoidReturnFromBlocks
repository_storage_move.start!
end
raise SameFilesystemError if same_filesystem?(repository.storage, destination_storage_name) raise SameFilesystemError if same_filesystem?(repository.storage, destination_storage_name)
......
...@@ -1530,7 +1530,7 @@ ...@@ -1530,7 +1530,7 @@
:urgency: :low :urgency: :low
:resource_boundary: :unknown :resource_boundary: :unknown
:weight: 1 :weight: 1
:idempotent: :idempotent: true
:tags: [] :tags: []
- :name: prometheus_create_default_alerts - :name: prometheus_create_default_alerts
:feature_category: :incident_management :feature_category: :incident_management
......
# frozen_string_literal: true # frozen_string_literal: true
class ProjectUpdateRepositoryStorageWorker # rubocop:disable Scalability/IdempotentWorker class ProjectUpdateRepositoryStorageWorker
include ApplicationWorker include ApplicationWorker
idempotent!
feature_category :gitaly feature_category :gitaly
def perform(project_id, new_repository_storage_key, repository_storage_move_id = nil) def perform(project_id, new_repository_storage_key, repository_storage_move_id = nil)
......
---
title: Make ProjectUpdateRepositoryStorageWorker idempotent
merge_request: 35483
author:
type: fixed
...@@ -14,5 +14,13 @@ FactoryBot.define do ...@@ -14,5 +14,13 @@ FactoryBot.define do
trait :started do trait :started do
state { ProjectRepositoryStorageMove.state_machines[:state].states[:started].value } state { ProjectRepositoryStorageMove.state_machines[:state].states[:started].value }
end end
trait :finished do
state { ProjectRepositoryStorageMove.state_machines[:state].states[:finished].value }
end
trait :failed do
state { ProjectRepositoryStorageMove.state_machines[:state].states[:failed].value }
end
end end
end end
...@@ -327,7 +327,7 @@ RSpec.describe Projects::ForkService do ...@@ -327,7 +327,7 @@ RSpec.describe Projects::ForkService do
destination_storage_name: 'test_second_storage' destination_storage_name: 'test_second_storage'
) )
Projects::UpdateRepositoryStorageService.new(storage_move).execute Projects::UpdateRepositoryStorageService.new(storage_move).execute
fork_after_move = fork_project(project) fork_after_move = fork_project(project.reload)
pool_repository_before_move = PoolRepository.joins(:shard) pool_repository_before_move = PoolRepository.joins(:shard)
.find_by(source_project: project, shards: { name: 'default' }) .find_by(source_project: project, shards: { name: 'default' })
pool_repository_after_move = PoolRepository.joins(:shard) pool_repository_after_move = PoolRepository.joins(:shard)
......
...@@ -45,6 +45,7 @@ RSpec.describe Projects::UpdateRepositoryStorageService do ...@@ -45,6 +45,7 @@ RSpec.describe Projects::UpdateRepositoryStorageService do
.and_call_original .and_call_original
result = subject.execute result = subject.execute
project.reload
expect(result).to be_success expect(result).to be_success
expect(project).not_to be_repository_read_only expect(project).not_to be_repository_read_only
...@@ -115,12 +116,37 @@ RSpec.describe Projects::UpdateRepositoryStorageService do ...@@ -115,12 +116,37 @@ RSpec.describe Projects::UpdateRepositoryStorageService do
.and_return(checksum) .and_return(checksum)
result = subject.execute result = subject.execute
project.reload
expect(result).to be_success expect(result).to be_success
expect(project.repository_storage).to eq('test_second_storage') expect(project.repository_storage).to eq('test_second_storage')
expect(project.reload_pool_repository).to be_nil expect(project.reload_pool_repository).to be_nil
end end
end end
context 'when the repository move is finished' do
let(:repository_storage_move) { create(:project_repository_storage_move, :finished, project: project, destination_storage_name: destination) }
it 'is idempotent' do
expect do
result = subject.execute
expect(result).to be_success
end.not_to change(repository_storage_move, :state)
end
end
context 'when the repository move is failed' do
let(:repository_storage_move) { create(:project_repository_storage_move, :failed, project: project, destination_storage_name: destination) }
it 'is idempotent' do
expect do
result = subject.execute
expect(result).to be_success
end.not_to change(repository_storage_move, :state)
end
end
end end
context 'with wiki repository' do context 'with wiki repository' do
......
...@@ -47,6 +47,7 @@ RSpec.shared_examples 'moves repository to another storage' do |repository_type| ...@@ -47,6 +47,7 @@ RSpec.shared_examples 'moves repository to another storage' do |repository_type|
old_repository_path = repository.full_path old_repository_path = repository.full_path
result = subject.execute result = subject.execute
project.reload
expect(result).to be_success expect(result).to be_success
expect(project).not_to be_repository_read_only expect(project).not_to be_repository_read_only
......
# frozen_string_literal: true # frozen_string_literal: true
require 'spec_helper' require 'spec_helper'
require 'securerandom'
RSpec.describe ProjectUpdateRepositoryStorageWorker do RSpec.describe ProjectUpdateRepositoryStorageWorker do
let(:project) { create(:project, :repository) } let(:project) { create(:project, :repository) }
......
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