35

我正在尝试使用 DelayedJob,但作业失败,在数据库中出现以下错误:

{延迟::反序列化错误
/Library/Ruby/Gems/1.8/gems/delayed_job-2.1.3/lib/delayed/serialization/active_record.rb:7:in `yaml_new'
/System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/lib/ruby/1.8/yaml.rb:133:in `transfer'
/System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/lib/ruby/1.8/yaml.rb:133:in `node_import'
/System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/lib/ruby/1.8/yaml.rb:133:in `load'
/System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/lib/ruby/1.8/yaml.rb:133:in `load'
/Library/Ruby/Gems/1.8/gems/delayed_job-2.1.3/lib/delayed/backend/base.rb:79:in `payload_object'
/Library/Ruby/Gems/1.8/gems/delayed_job-2.1.3/lib/delayed/backend/base.rb:87:in `invoke_job_without_newrelic_transaction_trace'
(eval):3:in `invoke_job'
/Library/Ruby/Gems/1.8/gems/newrelic_rpm-2.13.4/lib/new_relic/agent/instrumentation/controller_instrumentation.rb:252:in `perform_action_with_newrelic_trace'
/Library/Ruby/Gems/1.8/gems/newrelic_rpm-2.13.4/lib/new_relic/agent/method_tracer.rb:141:in `trace_execution_scoped'
/Library/Ruby/Gems/1.8/gems/newrelic_rpm-2.13.4/lib/new_relic/agent/instrumentation/controller_instrumentation.rb:247:in `perform_action_with_newrelic_trace'
(eval):2:in `invoke_job'
/Library/Ruby/Gems/1.8/gems/delayed_job-2.1.3/lib/delayed/worker.rb:120:in `run'
/System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/lib/ruby/1.8/timeout.rb:62:in `timeout'
/Library/Ruby/Gems/1.8/gems/delayed_job-2.1.3/lib/delayed/worker.rb:120:in `run'
/System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/lib/ruby/1.8/benchmark.rb:308:in `realtime'
/Library/Ruby/Gems/1.8/gems/delayed_job-2.1.3/lib/delayed/worker.rb:119:in `run'
/Library/Ruby/Gems/1.8/gems/delayed_job-2.1.3/lib/delayed/worker.rb:177:in `reserve_and_run_one_job'
/Library/Ruby/Gems/1.8/gems/delayed_job-2.1.3/lib/delayed/worker.rb:104:in `work_off'
/Library/Ruby/Gems/1.8/gems/delayed_job-2.1.3/lib/delayed/worker.rb:103:in `times'
/Library/Ruby/Gems/1.8/gems/delayed_job-2.1.3/lib/delayed/worker.rb:103:in `work_off'
/Library/Ruby/Gems/1.8/gems/delayed_job-2.1.3/lib/delayed/worker.rb:78:in `start'
/System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/lib/ruby/1.8/benchmark.rb:308:in `realtime'
/Library/Ruby/Gems/1.8/gems/delayed_job-2.1.3/lib/delayed/worker.rb:77:in `start'
/Library/Ruby/Gems/1.8/gems/delayed_job-2.1.3/lib/delayed/worker.rb:74:in `loop'
/Library/Ruby/Gems/1.8/gems/delayed_job-2.1.3/lib/delayed/worker.rb:74:in `start'
/Library/Ruby/Gems/1.8/gems/delayed_job-2.1.3/lib/delayed/tasks.rb:9
/Library/Ruby/Gems/1.8/gems/rake-0.8.7/lib/rake.rb:636:in `call'
/Library/Ruby/Gems/1.8/gems/rake-0.8.7/lib/rake.rb:636:in `execute'
/Library/Ruby/Gems/1.8/gems/rake-0.8.7/lib/rake.rb:631:in `each'
/Library/Ruby/Gems/1.8/gems/rake-0.8.7/lib/rake.rb:631:in `execute'
/Library/Ruby/Gems/1.8/gems/rake-0.8.7/lib/rake.rb:597:in `invoke_with_call_chain'
/System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/lib/ruby/1.8/monitor.rb:242:in `synchronize'
/Library/Ruby/Gems/1.8/gems/rake-0.8.7/lib/rake.rb:590:in `invoke_with_call_chain'
/Library/Ruby/Gems/1.8/gems/rake-0.8.7/lib/rake.rb:583:in `invoke'
/Library/Ruby/Gems/1.8/gems/rake-0.8.7/lib/rake.rb:2051:in `invoke_task'
/Library/Ruby/Gems/1.8/gems/rake-0.8.7/lib/rake.rb:2029:in `top_level'
/Library/Ruby/Gems/1.8/gems/rake-0.8.7/lib/rake.rb:2029:in `每个'
/Library/Ruby/Gems/1.8/gems/rake-0.8.7/lib/rake.rb:2029:in `top_level'
/Library/Ruby/Gems/1.8/gems/rake-0.8.7/lib/rake.rb:2068:in `standard_exception_handling'
/Library/Ruby/Gems/1.8/gems/rake-0.8.7/lib/rake.rb:2023:in `top_level'
/Library/Ruby/Gems/1.8/gems/rake-0.8.7/lib/rake.rb:2001:in `run'
/Library/Ruby/Gems/1.8/gems/rake-0.8.7/lib/rake.rb:2068:in `standard_exception_handling'
/Library/Ruby/Gems/1.8/gems/rake-0.8.7/lib/rake.rb:1998:in `run'
/图书馆/Ruby/Gems/1.8/gems/rake-0.8.7/bin/rake:31
/usr/bin/rake:19:in `load'
/usr/bin/rake:19

不知道从哪里开始诊断。这以前从未发生过,我之前使用延迟作业来序列化模型对象而没有任何问题。这次为什么?

提前致谢!

4

7 回答 7

69

这不是真正的反序列化错误,它是一个简单的 Model.find(id) 查询上的 ActiveRecord 记录未找到错误。

如果您想知道详细信息,请将它们记录在delayed_job-2.1.3/lib/delayed/serialization/active_record.rb文件中,在救援声明中,就在延迟作业愚蠢地提出DeserializationError并丢弃有用信息之前。

于 2011-02-28T14:32:09.880 回答
12

米歇尔是对的。查看处理程序字段中的对象,例如“!ruby/ActiveRecord:YourClassName”

然后检查是否可以通过主键检索对象

在控制台中,您还可以通过执行以下操作来测试它:

# first job in your delayed queue
YAML.load(Delayed::Backend::ActiveRecord::Job.first.handler)
于 2011-03-27T23:11:04.257 回答
3

我相信当您针对未保存或已删除的 AR 对象运行作业时会发生这种情况,因为 AR 的反序列化会按 id 加载记录。如果您尝试延迟未保存的 AR 对象上的方法,则可能会引发异常。

于 2011-06-24T09:18:55.250 回答
1

当传递到数据库中的处理程序字段的参数比标准的 TEXT 列长时,DJ 也有一个记录在案的错误:

https://github.com/collectiveidea/delayed_job/issues/491

如果这恰好是您的问题,将列更改为 MEDIUMINT 应该可以解决问题。

我在这样的迁移中做到了这一点:

change_column :delayed_jobs, :handler, :text, :limit => 16777215
ActiveRecord::Base.connection.execute("DELETE FROM delayed_jobs WHERE LENGTH(handler) >= 65535")

您可以通过简单的数据库查询来检查是否存在问题:

SELECT * FROM delayed_jobs WHERE LENGTH(handler) >= 65535
于 2013-12-20T17:46:50.140 回答
1

如果有人想让delayed_job 以无操作的方式完成工作,您可以在初始化程序中使用以下代码进行猴子补丁:

https://gist.github.com/spiilliton/8494752

于 2014-01-18T19:10:25.343 回答
0

今天,我也遇到了这个错误,经过忙碌的分析发现:

  1. delay_job 将方法和参数转换为 YAML 格式并将其存储到数据库中
  2. 可以使用select * from delayed_jobs;
  3. 当delayed_job 无法反序列化时,会发生反序列化错误。

可能的原因可能是:

  1. args["xyz"] 在调用 delay_job 之前使用 & 内部工作人员将其用作 args[:xyz]
  2. 有时额外的参数与对象一起传递给delayed_job 时间delayed_job 无法构建对象,因为它是无关紧要的访问。

我希望这个能帮上忙!

于 2011-03-02T19:02:02.293 回答
0

有时当我们升级库时,延迟的作业仍然保留旧的引用。

尝试在日志中找到delayed_job的id并播放将其处理程序解析为ruby以找到错误的引用

j = DelayedJob.find(XXX)
data = YAML.load_dj(j.handler)
data.to_ruby

我提出了一个请求来帮助解决这个问题。

同时你可以使用这条线

# config/initializers/delayed_job.rb

# Monkey patch to use old class references
module Psych

  class << self; attr_accessor :old_class_references end
  @old_class_references = {}

  class ClassLoader
    private

    def find klassname
      klassname = ::Psych.old_class_references[klassname] || klassname
      @cache[klassname] ||= resolve(klassname)
    end
  end

  module Visitors
    class ToRuby < Psych::Visitors::Visitor
      def revive klass, node
        if klass.is_a? String
          klassname = ::Psych.old_class_references[klass] || klass
          klass = Kernel.const_get(klassname) rescue klassname
        end
        s = register(node, klass.allocate)
        init_with(s, revive_hash({}, node), node)
      end
    end
  end
end

# Add all old dependencies (hash keys) pointing to new references (hash values)
Psych.old_class_references = {
  'ActiveRecord::AttributeSet' => 'ActiveModel::AttributeSet'
  # ...
}
于 2019-06-07T17:25:31.737 回答