DelayedJobを使用しようとしていますが、ジョブが失敗し、データベースに次のエラーが表示されます。
{Delayed :: DeserializationError /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。フレームワーク/バージョン/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/delayd_job-2.1.3/lib/delayd/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/delayd/worker.rb:119:in `run ' /Library/Ruby/Gems/1.8/gems/delayed_job-2.1.3/lib/delayd/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_o ff ' /Library/Ruby/Gems/1.8/gems/delayed_job-2.1.3/lib/delayed/worker.rb:103:in`times' /Library/Ruby/Gems/1.8/gems/delayd_job-2.1.3/lib/delayd/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/delayd_job-2.1.3/lib/delayd/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/rak e.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' /Library/Ruby/Gems/1.8/gems/rake-0.8.7/bin/rake:31 /usr/bin/rake:19:in `load ' /usr/bin/rake:19
これを診断するためにどこから始めればよいかわからない。これはこれまでに発生したことはなく、以前は遅延ジョブを使用してモデルオブジェクトを問題なくシリアル化しました。今回はなぜですか?
前もって感謝します!
これは実際には逆シリアル化エラーではなく、単純なModel.find(id)クエリでのActiveRecordレコードが見つかりませんエラーです。
詳細を知りたい場合は、遅延ジョブが愚かにDeserializationError
を上げて有用な情報を破棄する直前に、rescueステートメントのdelayed_job-2.1.3/lib/delayed/serialization/active_record.rb
ファイルに記録してください。
ミシエルは正しい。 「!Ruby/ActiveRecord:YourClassName」のようなオブジェクトのハンドラーフィールドを見てください
次に、主キーを介してオブジェクトを取得できるかどうかを確認します
コンソールから、次のようにしてこれをテストすることもできます。
# first job in your delayed queue
YAML.load(Delayed::Backend::ActiveRecord::Job.first.handler)
これは、ARの逆シリアル化によってレコードがIDで読み込まれるため、保存されていない、または削除されたARオブジェクトに対してジョブを実行したときに発生すると思います。保存されていないARオブジェクトのメソッドを遅らせようとすると、おそらく例外がスローされます。
誰かがdelayed_jobをno-opとしてジョブを終了させたい場合は、初期化子でこのコードを使用してモンキーパッチを適用できます。
DBのハンドラフィールドに渡されるパラメータが標準の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")
単純なDBクエリの問題かどうかを確認できます。
SELECT * FROM delayed_jobs WHERE LENGTH(handler) >= 65535
今日、私もこのエラーに苦しみ、多忙な分析を行った後、次のことがわかりました。
select * from delayed_jobs
を使用して見つけることができます。考えられる原因は次のとおりです。
これがお役に立てば幸いです。
Libsをアップグレードしても、遅延したジョブは古い参照を保持することがあります。
ログで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'
# ...
}