I'm using DelayedJob and I'd like to update my Rails 4.2 app to use ActiveJob. The problem is that I have a bunch of custom jobs that look like this:
AssetDeleteJob = Struct.new(:user_id, :params) do
def perform
# code
end
# more methods n' stuff
end
Then in a controller somewhere the job is enqueued with this syntax:
@asset_delete_job = AssetDeleteJob.new(current_admin_user.id, params)
Delayed::Job.enqueue @asset_delete_job
I'd like to find the equivalent for ActiveJob. The above is basically straight from the DJ docs. Using it to enqueue a single call is as simple as calling the job's perform method, just like with DJ. But mine are more complex and require DJ's Struct syntax and the arguments passed to it.
Here's what I've tried so far:
class AssetDeleteJob < ActiveJob::Base
queue_as :default
def initialize(user_id, params)
@user_id = user_id
@params = params
end
def perform
#code
end
# more methods n' stuff
end
job = AssetDeleteJob.new(1, {ids: [1,2,3]})
Unfortunately, the instantiated object has no #perform_later method as I would expect. It does have #enqueue, but I get an odd error:
Could not log "enqueue.active_job" event. NoMethodError: undefined method `any?' for nil:NilClass
...followed by a stack trace in an array, ending in
NoMethodError: undefined method `map' for nil:NilClass
An odd couple of errors, but I might not be supposed to be accessing #enqueue directly. The above seems like it's pretty on the nose as far as what ActiveJob is looking for. What am I missing?
Active Job is a framework for declaring jobs and making them run on a variety of queueing backends. These jobs can be everything from regularly scheduled clean-ups, to billing charges, to mailings. Anything that can be chopped up into small units of work and run in parallel, really.
Enqueue jobs The different enqueuing options are the following: wait : With this, the job is enqueued after the mentioned time period. wait_until : With this, the job is enqueued after that the specified time has elapsed. queue : With this, the job is added to the specified queue.
Restart Delayed Job on deploy You must remove that one now if you have it. It basically does the same thing that we will add now but without using upstart. We will now create a new file that will host our start, stop and restart tasks. Create a file at lib/capistrano/tasks/delayed_job.
Delayed Job, also known as DJ, makes it easy to add background tasks to your Rails applications on Heroku. You can also use Resque and many other popular background queueing libraries. Delayed Job uses your database as a queue to process background jobs.
I can see two problems. First, you've defined the initialize
method in your custom job class, thereby overwriting the initialize
method in the ActiveJob
class. This is what's causing the exception to be thrown. I'm not sure if you can fiddle about with instantiation of active jobs. Second, you're trying to call the class method perform_later
on an instance of that class, which ruby won't allow.
It's simple to fix, just add the arguments to the perform
method in your custom class instead:
class AssetDeleteJob < ActiveJob::Base
#code
def perform(user_id, params)
#do a thing
end
#more code
end
and then queue the job by calling something like:
AssetDeleteJob.perform_later(1, {ids: [1,2,3]})
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With