From e6c22076f8e3d24e8351a8c3cfc350f4d907b5d2 Mon Sep 17 00:00:00 2001 From: Ian Young Date: Mon, 28 Feb 2022 16:50:52 -0600 Subject: [PATCH] Option to enable scoped block for DelayedJob plugin When enabled, this adds job data to any Rollbar reporting that happens within the job, and prevents changes to the scope from polluting the global scope for other jobs. --- lib/rollbar/configuration.rb | 2 + lib/rollbar/plugins/delayed_job/plugin.rb | 7 ++- spec/rollbar/plugins/delayed_job_spec.rb | 57 +++++++++++++++++++++++ 3 files changed, 65 insertions(+), 1 deletion(-) diff --git a/lib/rollbar/configuration.rb b/lib/rollbar/configuration.rb index ec872f4a..43dc0671 100644 --- a/lib/rollbar/configuration.rb +++ b/lib/rollbar/configuration.rb @@ -22,6 +22,7 @@ class Configuration :disable_monkey_patch, :disable_rack_monkey_patch, :dj_threshold, + :dj_use_scoped_block, :enable_error_context, :enabled, :endpoint, @@ -102,6 +103,7 @@ def initialize @disable_rack_monkey_patch = false @enable_error_context = true @dj_threshold = 0 + @dj_use_scoped_block = false @async_skip_report_handler = nil @enabled = nil # set to true when configure is called @endpoint = DEFAULT_ENDPOINT diff --git a/lib/rollbar/plugins/delayed_job/plugin.rb b/lib/rollbar/plugins/delayed_job/plugin.rb index 64783d7e..f996a7c1 100644 --- a/lib/rollbar/plugins/delayed_job/plugin.rb +++ b/lib/rollbar/plugins/delayed_job/plugin.rb @@ -48,7 +48,12 @@ def self.wrap_worker! def self.invoke_job_callback proc do |job, *args, &block| begin - block.call(job, *args) + if Rollbar.configuration.dj_use_scoped_block + data = Rollbar::Delayed.build_job_data(job) + Rollbar.scoped(:request => data) { block.call(job, *args) } + else + block.call(job, *args) + end rescue StandardError => e report(e, job) diff --git a/spec/rollbar/plugins/delayed_job_spec.rb b/spec/rollbar/plugins/delayed_job_spec.rb index 25d111b5..d342ae18 100644 --- a/spec/rollbar/plugins/delayed_job_spec.rb +++ b/spec/rollbar/plugins/delayed_job_spec.rb @@ -14,6 +14,12 @@ def do_job_please!(_a, _b) end end + class PassingJob + def do_job_please!(_a, _b) + Rollbar.log("A job!") + end + end + before do Delayed::Backend::Test.prepare_worker @@ -49,6 +55,57 @@ def do_job_please!(_a, _b) end end + describe 'scope within job' do + context 'when Rollbar.configuration.dj_use_scoped_block is false (default)' do + before do + Rollbar.configuration.dj_use_scoped_block = false + end + + it 'does not wrap job in .scoped block' do + expect(Rollbar).not_to receive(:scoped).and_call_original + PassingJob.new.delay.do_job_please!(:foo, :bar) + end + + it 'does not include job data in scope' do + job_scope = nil + + Rollbar.stub(:log) do |_msg| + job_scope = Rollbar.scope_object + nil + end + + PassingJob.new.delay.do_job_please!(:foo, :bar) + + expect(job_scope).not_to have_key(:request) + end + end + + context 'when Rollbar.configuration.dj_use_scoped_block is true' do + before do + Rollbar.configuration.dj_use_scoped_block = true + end + + it 'wraps job in .scoped block' do + expect(Rollbar).to receive(:scoped).and_call_original + PassingJob.new.delay.do_job_please!(:foo, :bar) + end + + it 'includes job data in scope' do + job_scope = nil + + Rollbar.stub(:log) do |_msg| + job_scope = Rollbar.scope_object + nil + end + + PassingJob.new.delay.do_job_please!(:foo, :bar) + + expect(job_scope).to have_key(:request) + expect(job_scope[:request]).to include("name" => "PassingJob#do_job_please!") + end + end + end + context 'with failed deserialization' do let(:old_expected_args) do [/Delayed::DeserializationError/, { :use_exception_level_filters => true }]