Can't figure out Delayed::DeserializationError

2019-08-10 04:36发布

问题:

I am running delayed_job 3.0.5 (delayed_job_active_record 0.4.1) with Rails 3.2.12. I am having problems with some of my jobs failing because of "Deserialization". Here is a really simple example of one of the failing handlers:

--- !ruby/struct:Delayed::PerformableMethod
object: LOAD;Project;924951
method: :send_project_open_close_without_delay
args: []

When I try to invoke this job:

Delayed::DeserializationError: Job failed to load: undefined method `members' for nil:NilClass.

Everyone seems to think this is caused by an AR object that no longer exists. In my case, I can run the handler just fine:

Project.find(924951).send_open_close_without_delay

What else could be causing the error?

回答1:

I think I also experienced this issue when we upgrade to rails 3.2. The error I got was caused by the yaml handler used by delayed job. Try adding the following to config/boot.rb

require 'rubygems'
require 'yaml'
YAML::ENGINE.yamler = 'syck'


回答2:

Just in case anyone ever runs into this issue. I figured out the cause was some of the jobs were injected with an older version of Delayed Job. So when the newer Delayed Job attempted to process them, it was unable to deserialize the handler.



回答3:

This was caused by an upgrade to Delayed::Job that changed the serialization handler AND changed the type of object used for PerformableMethod. If you want to fix all old jobs and stick with the new defaults for Delayed::Job, you can fix failing ones with this query:

Delayed::Job.where('failed_at is not null').each do |dj|
  dj.handler = dj.handler.gsub('struct:Delayed', 'object:Delayed')
  Delayed::Worker.new.run(dj)
end

The change occurred around here: https://github.com/collectiveidea/delayed_job/commit/7b8a79a72c0ee5d8bac4bc0b183d1cce9cedff85

Making PerformableMethod a class instead of a Struct.