Commit 46ed494d authored by Mayra Cabrera's avatar Mayra Cabrera

Merge branch 'remove-job-deduplication-feature-flags' into 'master'

Remove implicit job deduplication feature flags

See merge request gitlab-org/gitlab!48031
parents c11a32bc f6f2024a
...@@ -52,7 +52,11 @@ module Reenqueuer ...@@ -52,7 +52,11 @@ module Reenqueuer
private private
def reenqueue(*args) def reenqueue(*args)
self.class.perform_async(*args) if yield result = yield
self.class.perform_async(*args) if result
result
end end
# Override as needed # Override as needed
......
...@@ -251,26 +251,6 @@ module AuthorizedProjectUpdate ...@@ -251,26 +251,6 @@ module AuthorizedProjectUpdate
end end
``` ```
#### Troubleshooting
If the automatic deduplication were to cause issues in certain
queues. This can be temporarily disabled by enabling a feature flag
named `disable_<queue name>_deduplication`. For example to disable
deduplication for the `AuthorizedProjectsWorker`, we would enable the
feature flag `disable_authorized_projects_deduplication`.
From ChatOps:
```shell
/chatops run feature set disable_authorized_projects_deduplication true
```
From the rails console:
```ruby
Feature.enable!(:disable_authorized_projects_deduplication)
```
## Limited capacity worker ## Limited capacity worker
It is possible to limit the number of concurrent running jobs for a worker class It is possible to limit the number of concurrent running jobs for a worker class
......
...@@ -70,10 +70,6 @@ module Gitlab ...@@ -70,10 +70,6 @@ module Gitlab
jid != existing_jid jid != existing_jid
end end
def droppable?
idempotent? && ::Feature.disabled?("disable_#{queue_name}_deduplication", type: :ops)
end
def scheduled_at def scheduled_at
job['at'] job['at']
end end
...@@ -85,6 +81,13 @@ module Gitlab ...@@ -85,6 +81,13 @@ module Gitlab
worker_klass.get_deduplication_options worker_klass.get_deduplication_options
end end
def idempotent?
return false unless worker_klass
return false unless worker_klass.respond_to?(:idempotent?)
worker_klass.idempotent?
end
private private
attr_reader :queue_name, :job attr_reader :queue_name, :job
...@@ -128,13 +131,6 @@ module Gitlab ...@@ -128,13 +131,6 @@ module Gitlab
def idempotency_string def idempotency_string
"#{worker_class_name}:#{arguments.join('-')}" "#{worker_class_name}:#{arguments.join('-')}"
end end
def idempotent?
return false unless worker_klass
return false unless worker_klass.respond_to?(:idempotent?)
worker_klass.idempotent?
end
end end
end end
end end
......
...@@ -13,7 +13,7 @@ module Gitlab ...@@ -13,7 +13,7 @@ module Gitlab
if deduplicatable_job? && check! && duplicate_job.duplicate? if deduplicatable_job? && check! && duplicate_job.duplicate?
job['duplicate-of'] = duplicate_job.existing_jid job['duplicate-of'] = duplicate_job.existing_jid
if duplicate_job.droppable? if duplicate_job.idempotent?
Gitlab::SidekiqLogging::DeduplicationLogger.instance.log( Gitlab::SidekiqLogging::DeduplicationLogger.instance.log(
job, "dropped #{strategy_name}", duplicate_job.options) job, "dropped #{strategy_name}", duplicate_job.options)
return false return false
......
...@@ -131,31 +131,6 @@ RSpec.describe Gitlab::SidekiqMiddleware::DuplicateJobs::DuplicateJob, :clean_gi ...@@ -131,31 +131,6 @@ RSpec.describe Gitlab::SidekiqMiddleware::DuplicateJobs::DuplicateJob, :clean_gi
end end
end end
describe '#droppable?' do
where(:idempotent, :prevent_deduplication) do
# [true, false].repeated_permutation(2)
[[true, true],
[true, false],
[false, true],
[false, false]]
end
with_them do
before do
allow(AuthorizedProjectsWorker).to receive(:idempotent?).and_return(idempotent)
stub_feature_flags("disable_#{queue}_deduplication" => prevent_deduplication)
end
it 'is droppable when all conditions are met' do
if idempotent && !prevent_deduplication
expect(duplicate_job).to be_droppable
else
expect(duplicate_job).not_to be_droppable
end
end
end
end
describe '#scheduled_at' do describe '#scheduled_at' do
let(:scheduled_at) { 42 } let(:scheduled_at) { 42 }
let(:job) do let(:job) do
...@@ -181,6 +156,46 @@ RSpec.describe Gitlab::SidekiqMiddleware::DuplicateJobs::DuplicateJob, :clean_gi ...@@ -181,6 +156,46 @@ RSpec.describe Gitlab::SidekiqMiddleware::DuplicateJobs::DuplicateJob, :clean_gi
end end
end end
describe '#idempotent?' do
context 'when worker class does not exist' do
let(:job) { { 'class' => '' } }
it 'returns false' do
expect(duplicate_job).not_to be_idempotent
end
end
context 'when worker class does not respond to #idempotent?' do
before do
stub_const('AuthorizedProjectsWorker', Class.new)
end
it 'returns false' do
expect(duplicate_job).not_to be_idempotent
end
end
context 'when worker class is not idempotent' do
before do
allow(AuthorizedProjectsWorker).to receive(:idempotent?).and_return(false)
end
it 'returns false' do
expect(duplicate_job).not_to be_idempotent
end
end
context 'when worker class is idempotent' do
before do
allow(AuthorizedProjectsWorker).to receive(:idempotent?).and_return(true)
end
it 'returns true' do
expect(duplicate_job).to be_idempotent
end
end
end
def set_idempotency_key(key, value = '1') def set_idempotency_key(key, value = '1')
Sidekiq.redis { |r| r.set(key, value) } Sidekiq.redis { |r| r.set(key, value) }
end end
......
...@@ -38,7 +38,7 @@ RSpec.shared_examples 'deduplicating jobs when scheduling' do |strategy_name| ...@@ -38,7 +38,7 @@ RSpec.shared_examples 'deduplicating jobs when scheduling' do |strategy_name|
it 'adds the jid of the existing job to the job hash' do it 'adds the jid of the existing job to the job hash' do
allow(fake_duplicate_job).to receive(:scheduled?).and_return(false) allow(fake_duplicate_job).to receive(:scheduled?).and_return(false)
allow(fake_duplicate_job).to receive(:check!).and_return('the jid') allow(fake_duplicate_job).to receive(:check!).and_return('the jid')
allow(fake_duplicate_job).to receive(:droppable?).and_return(true) allow(fake_duplicate_job).to receive(:idempotent?).and_return(true)
allow(fake_duplicate_job).to receive(:options).and_return({}) allow(fake_duplicate_job).to receive(:options).and_return({})
job_hash = {} job_hash = {}
...@@ -62,7 +62,7 @@ RSpec.shared_examples 'deduplicating jobs when scheduling' do |strategy_name| ...@@ -62,7 +62,7 @@ RSpec.shared_examples 'deduplicating jobs when scheduling' do |strategy_name|
receive(:check!) receive(:check!)
.with(Gitlab::SidekiqMiddleware::DuplicateJobs::DuplicateJob::DUPLICATE_KEY_TTL) .with(Gitlab::SidekiqMiddleware::DuplicateJobs::DuplicateJob::DUPLICATE_KEY_TTL)
.and_return('the jid')) .and_return('the jid'))
allow(fake_duplicate_job).to receive(:droppable?).and_return(true) allow(fake_duplicate_job).to receive(:idempotent?).and_return(true)
job_hash = {} job_hash = {}
expect(fake_duplicate_job).to receive(:duplicate?).and_return(true) expect(fake_duplicate_job).to receive(:duplicate?).and_return(true)
...@@ -82,7 +82,7 @@ RSpec.shared_examples 'deduplicating jobs when scheduling' do |strategy_name| ...@@ -82,7 +82,7 @@ RSpec.shared_examples 'deduplicating jobs when scheduling' do |strategy_name|
allow(fake_duplicate_job).to receive(:options).and_return({ including_scheduled: true }) allow(fake_duplicate_job).to receive(:options).and_return({ including_scheduled: true })
allow(fake_duplicate_job).to( allow(fake_duplicate_job).to(
receive(:check!).with(time_diff.to_i).and_return('the jid')) receive(:check!).with(time_diff.to_i).and_return('the jid'))
allow(fake_duplicate_job).to receive(:droppable?).and_return(true) allow(fake_duplicate_job).to receive(:idempotent?).and_return(true)
job_hash = {} job_hash = {}
expect(fake_duplicate_job).to receive(:duplicate?).and_return(true) expect(fake_duplicate_job).to receive(:duplicate?).and_return(true)
...@@ -104,13 +104,13 @@ RSpec.shared_examples 'deduplicating jobs when scheduling' do |strategy_name| ...@@ -104,13 +104,13 @@ RSpec.shared_examples 'deduplicating jobs when scheduling' do |strategy_name|
allow(fake_duplicate_job).to receive(:duplicate?).and_return(true) allow(fake_duplicate_job).to receive(:duplicate?).and_return(true)
allow(fake_duplicate_job).to receive(:options).and_return({}) allow(fake_duplicate_job).to receive(:options).and_return({})
allow(fake_duplicate_job).to receive(:existing_jid).and_return('the jid') allow(fake_duplicate_job).to receive(:existing_jid).and_return('the jid')
allow(fake_duplicate_job).to receive(:droppable?).and_return(true) allow(fake_duplicate_job).to receive(:idempotent?).and_return(true)
end end
it 'drops the job' do it 'drops the job' do
schedule_result = nil schedule_result = nil
expect(fake_duplicate_job).to receive(:droppable?).and_return(true) expect(fake_duplicate_job).to receive(:idempotent?).and_return(true)
expect { |b| schedule_result = strategy.schedule({}, &b) }.not_to yield_control expect { |b| schedule_result = strategy.schedule({}, &b) }.not_to yield_control
expect(schedule_result).to be(false) expect(schedule_result).to be(false)
......
...@@ -79,6 +79,10 @@ RSpec.describe Reenqueuer do ...@@ -79,6 +79,10 @@ RSpec.describe Reenqueuer do
job.perform job.perform
end end
it 'returns the original value from #perform' do
expect(job.perform).to eq(true)
end
end end
context 'when #perform returns falsey' do context 'when #perform returns falsey' do
...@@ -87,6 +91,10 @@ RSpec.describe Reenqueuer do ...@@ -87,6 +91,10 @@ RSpec.describe Reenqueuer do
job.perform job.perform
end end
it 'returns the original value from #perform' do
expect(job.perform).to eq(false)
end
end end
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