Fix regression where AJ#perform_now doesn't return the job's value:

- Fix #38040
This commit is contained in:
Edouard CHIN 2019-12-28 19:04:38 +01:00
parent 1414910502
commit 2cd05dda2b
3 changed files with 50 additions and 5 deletions

View File

@ -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

View File

@ -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

View File

@ -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