diff --git a/activejob/lib/active_job/callbacks.rb b/activejob/lib/active_job/callbacks.rb index ad6051f7b1..1bc20da630 100644 --- a/activejob/lib/active_job/callbacks.rb +++ b/activejob/lib/active_job/callbacks.rb @@ -101,6 +101,19 @@ module ActiveJob # end # end # + # You can access the return value of the job only if the execution wasn't halted. + # + # class VideoProcessJob < ActiveJob::Base + # around_perform do |job, block| + # value = block.call + # puts value # => "Hello World!" + # end + # + # def perform + # "Hello World!" + # end + # end + # def around_perform(*filters, &blk) set_callback(:perform, :around, *filters, &blk) end diff --git a/activejob/lib/active_job/execution.rb b/activejob/lib/active_job/execution.rb index faba8589ef..f1114fbc10 100644 --- a/activejob/lib/active_job/execution.rb +++ b/activejob/lib/active_job/execution.rb @@ -28,8 +28,15 @@ module ActiveJob # Performs the job immediately. The job is not sent to the queuing adapter # but directly executed by blocking the execution of others until it's finished. + # `perform_now` returns the value of your job's `perform` method. # - # MyJob.new(*args).perform_now + # class MyJob < ActiveJob::Base + # def perform + # "Hello World!" + # end + # end + # + # puts MyJob.new(*args).perform_now # => "Hello World!" def perform_now # Guard against jobs that were persisted before we started counting executions by zeroing out nil counters self.executions = (executions || 0) + 1 @@ -37,19 +44,18 @@ module ActiveJob deserialize_arguments_if_needed successfully_performed = false - run_callbacks :perform do + job = run_callbacks :perform do args = arguments options = args.extract_options! if options.empty? perform(*args) else perform(*args, **options) - end - successfully_performed = true + end.tap { successfully_performed = true } end warn_against_after_callbacks_execution_deprecation(_perform_callbacks) unless successfully_performed - successfully_performed + job rescue => exception rescue_with_handler(exception) || raise end diff --git a/activejob/test/cases/callbacks_test.rb b/activejob/test/cases/callbacks_test.rb index 3eee2a2cfd..3e56eb1ab7 100644 --- a/activejob/test/cases/callbacks_test.rb +++ b/activejob/test/cases/callbacks_test.rb @@ -16,6 +16,32 @@ class CallbacksTest < ActiveSupport::TestCase assert "CallbackJob ran around_perform_stop".in? performed_callback_job.history end + test "perform return value" do + job = Class.new(ActiveJob::Base) do + def perform + 123 + end + end + + assert_equal(123, job.perform_now) + end + + test "perform around_callbacks return value" do + value = nil + + Class.new(ActiveJob::Base) do + around_perform do |_, block| + value = block.call + end + + def perform + 123 + end + end.perform_now + + assert_equal(123, value) + end + test "enqueue callbacks" do enqueued_callback_job = CallbackJob.perform_later assert "CallbackJob ran before_enqueue".in? enqueued_callback_job.history