In one of our applications we use ActiveJob in combination with the Delayed::Job adapter. So in our application.rb
we define:
config.active_job.queue_adapter = :delayed_job
The problem here is, that we don’t get the provider_job_id
, which would allow us to get the created Delayed::Job
from the database.
In order to be able to get the provider_job_id
we need to add a plugin to the Delayed::Worker
. So we add this plugin in an initializer.
# config/initializers/delayed_job_job_id_provider.rb
class DelayedJobJobIdProvider < Delayed::Plugin
callbacks do |lifecycle|
lifecycle.before(:invoke_job) do |job|
job.payload_object.job_data["provider_job_id"] = job.id if job.payload_object.respond_to?(:job_data)
end
end
end
Delayed::Worker.plugins << DelayedJobJobIdProvider
This allows us to get the provider_job_id
from the ApplicationJob
directly. In our case we use this in the rescue_from
for ActiveJob::DeserializationError
. This error occurs when the Delayed::Job
is trying to access a record, that has been deleted.
class ApplicationJob < ActiveJob::Base
rescue_from(ActiveJob::DeserializationError) do |exception|
Delayed::Job.find(provider_job_id).update!(failed_at: Time.now, last_error: exception.message)
raise exception
end
end
We can then just find the specific Delayed::Job
by the provider_job_id
. This is useful if you want custom handling for the Delayed::Job
in case of an error, so you could for example decide if you want to keep the job or destroy it.
Happy Coding!