diff --git a/vendor/plugins/delayed_job/lib/delayed/backend/base.rb b/vendor/plugins/delayed_job/lib/delayed/backend/base.rb index 54ac56bd742..fffac011c95 100644 --- a/vendor/plugins/delayed_job/lib/delayed/backend/base.rb +++ b/vendor/plugins/delayed_job/lib/delayed/backend/base.rb @@ -40,6 +40,14 @@ module Delayed self.create(options) end end + + def in_delayed_job? + !!Thread.current[:in_delayed_job] + end + + def in_delayed_job=(val) + Thread.current[:in_delayed_job] = val + end end def failed? @@ -84,7 +92,9 @@ module Delayed # Moved into its own method so that new_relic can trace it. def invoke_job + Delayed::Job.in_delayed_job = true payload_object.perform + Delayed::Job.in_delayed_job = false end # Unlock this job (note: not saved to DB) diff --git a/vendor/plugins/delayed_job/lib/delayed/message_sending.rb b/vendor/plugins/delayed_job/lib/delayed/message_sending.rb index 447b596ced2..d5061d7c511 100644 --- a/vendor/plugins/delayed_job/lib/delayed/message_sending.rb +++ b/vendor/plugins/delayed_job/lib/delayed/message_sending.rb @@ -33,6 +33,15 @@ module Delayed *args) end + def send_later_unless_in_job(method, *args) + if Delayed::Job.in_delayed_job? + send(method, *args) + else + send_later(method, *args) + end + nil # can't rely on the type of return value, so return nothing + end + module ClassMethods def handle_asynchronously(method, enqueue_args = {}) aliased_method, punctuation = method.to_s.sub(/([?!=])$/, ''), $1 diff --git a/vendor/plugins/delayed_job/spec_canvas/delayed_method_spec.rb b/vendor/plugins/delayed_job/spec_canvas/delayed_method_spec.rb index 374e3297059..f55feccef9f 100644 --- a/vendor/plugins/delayed_job/spec_canvas/delayed_method_spec.rb +++ b/vendor/plugins/delayed_job/spec_canvas/delayed_method_spec.rb @@ -134,4 +134,34 @@ describe 'random ruby objects' do end end + describe "send_later_unless_in_job" do + module UnlessInJob + @runs = 0 + def self.runs; @runs; end + + def self.run + @runs += 1 + end + + def self.run_later + self.send_later_unless_in_job :run + end + end + + before do + UnlessInJob.class_eval { @runs = 0 } + end + + it "should perform immediately if in job" do + job = UnlessInJob.send_later :run_later + job.invoke_job + UnlessInJob.runs.should == 1 + end + + it "should queue up for later if not in job" do + UnlessInJob.run_later + UnlessInJob.runs.should == 0 + end + end + end diff --git a/vendor/plugins/delayed_job/spec_canvas/shared_backend_spec.rb b/vendor/plugins/delayed_job/spec_canvas/shared_backend_spec.rb index cfc6be848db..8654481a8c4 100644 --- a/vendor/plugins/delayed_job/spec_canvas/shared_backend_spec.rb +++ b/vendor/plugins/delayed_job/spec_canvas/shared_backend_spec.rb @@ -410,4 +410,17 @@ shared_examples_for 'a backend' do proc { Delayed::Periodic.cron('my SimpleJob', '*/15 * * * * *') {} }.should raise_error(ArgumentError) end end + + module InDelayedJobTest + def self.check_in_job + Delayed::Job.in_delayed_job?.should == true + end + end + + it "should set in_delayed_job?" do + job = InDelayedJobTest.send_later(:check_in_job) + Delayed::Job.in_delayed_job?.should == false + job.invoke_job + Delayed::Job.in_delayed_job?.should == false + end end