Commit af41bd41 authored by Grzegorz Bizon's avatar Grzegorz Bizon

Fix off-by-one error in background migration retries

parent 7b146ab6
...@@ -48,12 +48,17 @@ module Gitlab ...@@ -48,12 +48,17 @@ module Gitlab
# #
# arguments - The arguments to pass to the background migration's "perform" # arguments - The arguments to pass to the background migration's "perform"
# method. # method.
def self.perform(class_name, arguments, retries: 1) def self.perform(class_name, arguments, retries: 0)
const_get(class_name).new.perform(*arguments) const_get(class_name).new.perform(*arguments)
rescue => e rescue StandardError
Rails.logger.warn("Retrying background migration #{class_name} " \ if retries > 0
"with #{arguments}") Rails.logger.warn("Retrying background migration #{class_name} " \
(retries -= 1) > 0 ? retry : raise "with #{arguments}")
retries -= 1
retry
else
raise
end
end end
end end
end end
...@@ -63,14 +63,10 @@ describe Gitlab::BackgroundMigration do ...@@ -63,14 +63,10 @@ describe Gitlab::BackgroundMigration do
end end
context 'when standard error is being raised' do context 'when standard error is being raised' do
before do
allow(migration).to receive(:perform).with(10, 20)
.and_raise(StandardError, 'Migration error')
end
it 'recovers from an exception and retries the migration' do it 'recovers from an exception and retries the migration' do
expect(migration).to receive(:perform).with(10, 20) expect(migration).to receive(:perform).with(10, 20)
.exactly(3).times.ordered .and_raise(StandardError, 'Migration error')
.exactly(4).times.ordered
expect(migration).to receive(:perform).with(20, 30) expect(migration).to receive(:perform).with(20, 30)
.once.ordered .once.ordered
expect(Rails.logger).to receive(:warn) expect(Rails.logger).to receive(:warn)
...@@ -148,7 +144,17 @@ describe Gitlab::BackgroundMigration do ...@@ -148,7 +144,17 @@ describe Gitlab::BackgroundMigration do
expect(migration).to receive(:perform).with(10, 20) expect(migration).to receive(:perform).with(10, 20)
.and_raise(StandardError).once .and_raise(StandardError).once
expect { described_class.perform('Foo', [10, 20], retries: 0) } expect { described_class.perform('Foo', [10, 20], retries: 0) }
.to raise_error(StandardError)
end
end
context 'when retries count is one' do
it 'retries a background migration when needed' do
expect(migration).to receive(:perform).with(10, 20)
.and_raise(StandardError).twice
expect { described_class.perform('Foo', [10, 20], retries: 1) }
.to raise_error(StandardError) .to raise_error(StandardError)
end end
end end
...@@ -156,9 +162,9 @@ describe Gitlab::BackgroundMigration do ...@@ -156,9 +162,9 @@ describe Gitlab::BackgroundMigration do
context 'when retries count is larger than zero' do context 'when retries count is larger than zero' do
it 'retries a background migration when needed' do it 'retries a background migration when needed' do
expect(migration).to receive(:perform).with(10, 20) expect(migration).to receive(:perform).with(10, 20)
.and_raise(StandardError).exactly(3).times .and_raise(StandardError).exactly(4).times
expect { described_class.perform('Foo', [10, 20], retries: 3) } expect { described_class.perform('Foo', [10, 20], retries: 3) }
.to raise_error(StandardError) .to raise_error(StandardError)
end end
end end
......
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