Pertanyaan Bagaimana cara mengatasi kesalahan deserialization dalam pekerjaan yang tertunda?


Saya mencoba menggunakan DelayedJob dan pekerjaannya gagal, memberikan kesalahan berikut dalam database:

{Tertunda :: 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.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: di `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: di `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 `kali '
/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 `mengeksekusi '
/Library/Ruby/Gems/1.8/gems/rake-0.8.7/lib/rake.rb:631:in `masing-masing '
/Library/Ruby/Gems/1.8/gems/rake-0.8.7/lib/rake.rb:631:in `mengeksekusi '
/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 `menyinkronkan '
/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 `memohon '
/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 `masing-masing '
/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: di `load '
/ usr / bin / rake: 19

Tidak yakin harus mulai dari mana untuk mendiagnosis ini. Ini belum pernah terjadi sebelumnya dan saya telah menggunakan pekerjaan yang tertunda sebelumnya untuk membuat serial objek model tanpa masalah. Kenapa kali ini?

Terima kasih sebelumnya!


33
2018-02-16 23:01


asal


Jawaban:


Ini bukan benar-benar kesalahan deserialization, ini adalah kesalahan record-not-found ActiveRecord pada query Model.find (id) yang sederhana.

Jika Anda ingin mengetahui detailnya, masukkan mereka di delayed_job-2.1.3/lib/delayed/serialization/active_record.rb file, dalam pernyataan penyelamatan, sesaat sebelum pekerjaan tertunda secara bodoh memunculkan DeserializationError dan membuang informasi yang berguna.


67
2018-02-28 14:32



Michiel benar. Lihatlah bidang handler Anda untuk objek seperti "! Ruby / ActiveRecord: YourClassName"

Kemudian periksa apakah objek dapat diambil melalui kunci primer

Dari konsol Anda juga dapat menguji ini dengan melakukan sesuatu seperti:

# first job in your delayed queue
YAML.load(Delayed::Backend::ActiveRecord::Job.first.handler)

12
2018-03-27 23:11



Saya yakin ini terjadi ketika Anda menjalankan pekerjaan terhadap objek AR yang belum disimpan atau dihapus karena deserialization untuk AR memuat record oleh id. Pengecualian mungkin harus dibuang jika Anda mencoba menunda metode pada objek AR yang belum disimpan.


3
2018-06-24 09:18



Ada juga bug didokumentasikan dengan DJ ketika params masuk ke bidang handler di DB lebih panjang dari kolom TEXT standar:

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

Jika ini terjadi menjadi masalah Anda, mengubah kolom ke MEDIUMINT harus memperbaiki masalah.

Saya melakukan ini dalam migrasi seperti ini:

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

Anda dapat memeriksa untuk melihat apakah itu masalah dengan permintaan DB sederhana:

SELECT * FROM delayed_jobs WHERE LENGTH(handler) >= 65535

1
2017-12-20 17:46



Jika ada yang ingin membuat delayed_job, selesaikan pekerjaan sebagai no-op Anda dapat melakukan patch monyet dengan kode ini di penginisialisasi:

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


1
2018-01-18 19:10



Hari ini, saya juga menderita karena kesalahan ini dan setelah melakukan analisis sibuk, saya menemukan:

  1. delayed_job mengonversi metode & parameter ke format YAML dan menyimpannya ke dalam basis data
  2. Ini dapat ditemukan menggunakan select * from delayed_jobs;
  3. kesalahan deserialization terjadi ketika delayed_job tidak dapat deserialize itu.

Kemungkinan penyebabnya bisa:

  1. args ["xyz"] digunakan sebelum memanggil delayed_job & inside worker menggunakannya sebagai args [: xyz]
  2. Kadang-kadang argumen tambahan dilewatkan bersama dengan objek ke delayed_job yang waktu itu delayed_job gagal untuk membangun objek karena akses acuh tak acuh.

Semoga ini akan membantu!


0
2018-03-02 19:02