I've found that ActiveJob could triggered by MyJob.new.perform and MyJob.perform_now.
My question is: what's the difference between these two calls?
I've found that ActiveJob could triggered by MyJob.new.perform and MyJob.perform_now.
My question is: what's the difference between these two calls?
The perform_now method is a wrapper around the perform method of the ActiveJob::Execution class. The source code(shortened for answer) for both these methods can be found here on GitHub. The source code is as follows:
module ActiveJob
module Execution
extend ActiveSupport::Concern
include ActiveSupport::Rescuable
# Includes methods for executing and performing jobs instantly.
module ClassMethods
# Method 1
def perform_now(*args)
job_or_instantiate(*args).perform_now
end
end
# Instance method. Method 2
def perform_now
self.executions = (executions || 0) + 1
deserialize_arguments_if_needed
run_callbacks :perform do
perform(*arguments)
end
rescue => exception
rescue_with_handler(exception) || raise
end
# Method 3
def perform(*)
fail NotImplementedError
end
MyJob.perform_now
This call, invokes the class method, perform_now (Method 1 in the snippet), which internally instantiates an object of MyJob and calls the instance method perform_now (Method 2 in the snippet). This method deserializes arguments if required, and then runs callbacks that we may have defined in our job file for MyJob. After this, it calls the perform method(Method 3 in our snippet), which is an instance method of the ActiveJob::Execution class.
MyJob.new.perform
If we use this notation, we basically instantiate an instance of the job by ourselves, and then call the perform method (Method 3 of our snippet) on the job. By doing so, we skip the deserialization provided by perform_now and also skip running any callbacks written on our job, MyJob.
Illustrated with an example:
# app/jobs/my_job.rb
class UpdatePrStatusJob < ApplicationJob
before_perform do |job|
p "I'm in the before perform callback"
end
def perform(*args)
p "I'm performing the job"
end
end
MyJob.perform_now gives the output:
"I'm in the before perform callback"
"I'm performing the job"
whereas MyJob.new.perform gives the output:
"I'm performing the job"
This article by Karol Galanciak explains jobs in detail and should be an interesting read if you're looking for more information on how jobs work.