Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix max_retries Method #31

Merged
merged 3 commits into from
Sep 5, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -7,3 +7,4 @@
/pkg/
/spec/reports/
/tmp/
sidekiq-instrument-*
17 changes: 13 additions & 4 deletions lib/sidekiq/instrument/mixin.rb
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,15 @@ def worker_dog_options(worker)
end

def max_retries(worker)
retries = worker.class.get_sidekiq_options['retry'] || Sidekiq[:max_retries]
Copy link
Contributor Author

@orioldsm orioldsm Sep 5, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This was causing the worker to always default to the global Sidekiq[:max_retries] value even ifworker.class.get_sidekiq_options['retry'] was set to false, which is NOT the intended behavior.

return Sidekiq[:max_retries] if retries.to_s.eql?("true")
return 0 if retries.eql?("false")
retries
retries = fetch_worker_retry(worker)
case retries.to_s
when "true", ""
Sidekiq[:max_retries]
when "false"
0
else
retries
end
end

private
Expand All @@ -29,6 +34,10 @@ def class_name(worker)
worker.class.name.gsub('::', '_')
end

def fetch_worker_retry(worker)
worker.class.get_sidekiq_options['retry']
end

def underscore(string)
string.gsub(/::/, '/').
gsub(/([A-Z]+)([A-Z][a-z])/,'\1_\2').
Expand Down
2 changes: 1 addition & 1 deletion lib/sidekiq/instrument/version.rb
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
module Sidekiq
module Instrument
VERSION = '0.7.0'
VERSION = '0.7.1'
end
end
88 changes: 64 additions & 24 deletions spec/sidekiq-instrument/server_middleware_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,6 @@
context 'when an initial job succeeds' do
before do
Sidekiq[:max_retries] = 0
allow_any_instance_of(MyWorker).to receive(:get_sidekiq_options).and_return({ 'retry': 'true'})
end

it 'increments StatsD dequeue counter' do
Expand Down Expand Up @@ -85,7 +84,6 @@
before do
Sidekiq[:max_retries] = 1
allow_any_instance_of(MyWorker).to receive(:perform).and_raise('foo')
allow_any_instance_of(MyWorker).to receive(:get_sidekiq_options).and_return({ 'retry': 'true'})

# This makes the job look like a retry since we can't access the job argument
allow_any_instance_of(Sidekiq::Instrument::ServerMiddleware).to receive(:current_retries).and_return(0)
Expand Down Expand Up @@ -114,7 +112,6 @@
before do
Sidekiq[:max_retries] = 0
allow_any_instance_of(MyWorker).to receive(:perform).and_raise('foo')
allow_any_instance_of(MyWorker).to receive(:get_sidekiq_options).and_return({ 'retry': 'false'})
end

it 'increments the StatsD error counter' do
Expand All @@ -141,36 +138,79 @@
end
end

context 'job has retries left' do
before do
Sidekiq[:max_retries] = 1
allow_any_instance_of(MyWorker).to receive(:get_sidekiq_options).and_return({ 'retry': 'true'})
context 'when the worker has retries disabled' do
shared_examples 'it does not attempt to track retries' do |retry_value|
before do
Sidekiq[:max_retries] = 1
allow(MyWorker).to receive(:get_sidekiq_options).and_return({ "retry" => retry_value, "queue" => 'default' })
end

it 'does not increment the DogStatsD enqueue.retry counter' do
expect(
Sidekiq::Instrument::Statter.dogstatsd
).to receive(:increment).with('sidekiq.dequeue', expected_dog_options).once
expect(
Sidekiq::Instrument::Statter.dogstatsd
).not_to receive(:increment).with('sidekiq.enqueue.retry', expected_dog_options)
expect(Sidekiq::Instrument::Statter.dogstatsd).not_to receive(:time)
expect(
Sidekiq::Instrument::Statter.dogstatsd
).to receive(:increment).with('sidekiq.error', expected_dog_options).once

begin
MyWorker.perform_async
rescue StandardError
nil
end
end
end

it 'increments the DogStatsD enqueue.retry counter' do
expect(
Sidekiq::Instrument::Statter.dogstatsd
).to receive(:increment).with('sidekiq.dequeue', expected_dog_options).once
expect(
Sidekiq::Instrument::Statter.dogstatsd
).to receive(:increment).with('sidekiq.enqueue.retry', expected_dog_options).once
expect(Sidekiq::Instrument::Statter.dogstatsd).not_to receive(:time)
expect(
Sidekiq::Instrument::Statter.dogstatsd
).to receive(:increment).with('sidekiq.error', expected_dog_options).once
it_behaves_like 'it does not attempt to track retries', false

begin
MyWorker.perform_async
rescue StandardError
nil
it_behaves_like 'it does not attempt to track retries', 'false'

it_behaves_like 'it does not attempt to track retries', 0
end

context 'when the current job has retries left to attempt' do
shared_examples 'it tracks the retries with DogStatsD' do |retry_value|
before do
Sidekiq[:max_retries] = 2
allow(MyWorker).to receive(:get_sidekiq_options).and_return({ "retry" => retry_value, "queue" => 'default' })
end

it 'increments the DogStatsD enqueue.retry counter' do
expect(
Sidekiq::Instrument::Statter.dogstatsd
).to receive(:increment).with('sidekiq.dequeue', expected_dog_options).once
expect(
Sidekiq::Instrument::Statter.dogstatsd
).to receive(:increment).with('sidekiq.enqueue.retry', expected_dog_options).once
expect(Sidekiq::Instrument::Statter.dogstatsd).not_to receive(:time)
expect(
Sidekiq::Instrument::Statter.dogstatsd
).to receive(:increment).with('sidekiq.error', expected_dog_options).once

begin
MyWorker.perform_async
rescue StandardError
nil
end
end
end

it_behaves_like 'it tracks the retries with DogStatsD', 'true'

it_behaves_like 'it tracks the retries with DogStatsD', true

it_behaves_like 'it tracks the retries with DogStatsD', 5

it_behaves_like 'it tracks the retries with DogStatsD', nil
end

context 'on its last retry' do
context 'when the job is on its last retry attempt' do
before do
Sidekiq[:max_retries] = 1
allow_any_instance_of(MyWorker).to receive(:get_sidekiq_options).and_return({ 'retry': 'true'})

# This makes the job look like a retry since we can't access the job argument
allow_any_instance_of(Sidekiq::Instrument::ServerMiddleware).to receive(:current_retries).and_return(1)
Expand Down
Loading