Avoid race condition when stealing a background migration

We first pop a job from the Sidekiq queue / scheduled set and only if
this has been successfully deleted we process the job. This makes it
possible to minimize a possibility of a race condition happening.
This commit is contained in:
Grzegorz Bizon 2017-07-14 12:48:11 +02:00
parent beffbc8aa2
commit 39b96f02dc
2 changed files with 10 additions and 4 deletions

View File

@ -19,9 +19,7 @@ module Gitlab
next unless job.queue == self.queue
next unless migration_class == steal_class
perform(migration_class, migration_args)
job.delete
perform(migration_class, migration_args) if job.delete
end
end
end

View File

@ -23,13 +23,21 @@ describe Gitlab::BackgroundMigration do
end
it 'steals jobs from a queue' do
expect(queue[0]).to receive(:delete)
expect(queue[0]).to receive(:delete).and_return(true)
expect(described_class).to receive(:perform).with('Foo', [10, 20])
described_class.steal('Foo')
end
it 'does not steal job that has already been taken' do
expect(queue[0]).to receive(:delete).and_return(false)
expect(described_class).not_to receive(:perform).with('Foo', [10, 20])
described_class.steal('Foo')
end
it 'does not steal jobs for a different migration' do
expect(described_class).not_to receive(:perform)