35 votes

Comment résoudre l'erreur de désérialisation dans un travail retardé?

Je suis en train d'utiliser DelayedJob et le travail est à défaut, de donner le message d'erreur suivant dans la base de données:

{Différés::DeserializationError
/Library/Ruby/Gems/1.8/gems/delayed_job-2.1.3/lib/retard/de sérialisation/active_record.rb:7:dans "le yaml_new'
/System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/lib/ruby/1.8/yaml.rb:133:dans "transfert"
/System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/lib/ruby/1.8/yaml.rb:133:dans "le node_import'
/System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/lib/ruby/1.8/yaml.rb:133:dans la "charge"
/System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/lib/ruby/1.8/yaml.rb:133:dans la "charge"
/Library/Ruby/Gems/1.8/gems/delayed_job-2.1.3/lib/retard/backend/base.rb:79:dans "le payload_object'
/Library/Ruby/Gems/1.8/gems/delayed_job-2.1.3/lib/retard/backend/base.rb:87:dans "le invoke_job_without_newrelic_transaction_trace'
(eval):3:dans "le invoke_job'
/Library/Ruby/Gems/1.8/gems/newrelic_rpm-2.13.4/lib/new_relic/agent/instrumentation/controller_instrumentation.rb:252:dans "perform_action_with_newrelic_trace'
/Library/Ruby/Gems/1.8/gems/newrelic_rpm-2.13.4/lib/new_relic/agent/method_tracer.rb:141:en `trace_execution_scoped'
/Library/Ruby/Gems/1.8/gems/newrelic_rpm-2.13.4/lib/new_relic/agent/instrumentation/controller_instrumentation.rb:247:dans "perform_action_with_newrelic_trace'
(eval):2:en `invoke_job'
/Library/Ruby/Gems/1.8/gems/delayed_job-2.1.3/lib/retard/travailleur.rb:120:dans "exécuter"
/System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/lib/ruby/1.8/timeout.rb:62:dans `timeout'
/Library/Ruby/Gems/1.8/gems/delayed_job-2.1.3/lib/retard/travailleur.rb:120:dans "exécuter"
/System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/lib/ruby/1.8/indice de référence.rb:308:en `temps réel'
/Library/Ruby/Gems/1.8/gems/delayed_job-2.1.3/lib/retard/travailleur.rb:119:dans "exécuter"
/Library/Ruby/Gems/1.8/gems/delayed_job-2.1.3/lib/retard/travailleur.rb:177:en `reserve_and_run_one_job'
/Library/Ruby/Gems/1.8/gems/delayed_job-2.1.3/lib/retard/travailleur.rb:104:dans "le work_off'
/Library/Ruby/Gems/1.8/gems/delayed_job-2.1.3/lib/retard/travailleur.rb:103:dans "le temps"
/Library/Ruby/Gems/1.8/gems/delayed_job-2.1.3/lib/retard/travailleur.rb:103:dans "le work_off'
/Library/Ruby/Gems/1.8/gems/delayed_job-2.1.3/lib/retard/travailleur.rb:78:dans `démarrer'
/System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/lib/ruby/1.8/indice de référence.rb:308:en `temps réel'
/Library/Ruby/Gems/1.8/gems/delayed_job-2.1.3/lib/retard/travailleur.rb:77:dans `démarrer'
/Library/Ruby/Gems/1.8/gems/delayed_job-2.1.3/lib/retard/travailleur.rb:74:dans le "loop"
/Library/Ruby/Gems/1.8/gems/delayed_job-2.1.3/lib/retard/travailleur.rb:74:dans `démarrer'
/Library/Ruby/Gems/1.8/gems/delayed_job-2.1.3/lib/delayed/tâches.rb:9
/Library/Ruby/Gems/1.8/gems/rake-0.8.7/lib/râteau.rb:636:en "appel"
/Library/Ruby/Gems/1.8/gems/rake-0.8.7/lib/râteau.rb:636:dans `exécuter'
/Library/Ruby/Gems/1.8/gems/rake-0.8.7/lib/râteau.rb:631:dans `chaque'
/Library/Ruby/Gems/1.8/gems/rake-0.8.7/lib/râteau.rb:631:dans `exécuter'
/Library/Ruby/Gems/1.8/gems/rake-0.8.7/lib/râteau.rb:597:dans "le invoke_with_call_chain'
/System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/lib/ruby/1.8/moniteur.rb:242:dans "synchroniser"
/Library/Ruby/Gems/1.8/gems/rake-0.8.7/lib/râteau.rb:590:dans "le invoke_with_call_chain'
/Library/Ruby/Gems/1.8/gems/rake-0.8.7/lib/râteau.rb:583:en `appeler'
/Library/Ruby/Gems/1.8/gems/rake-0.8.7/lib/râteau.rb:2051:dans "le invoke_task'
/Library/Ruby/Gems/1.8/gems/rake-0.8.7/lib/râteau.rb:2029:dans "le top_level'
/Library/Ruby/Gems/1.8/gems/rake-0.8.7/lib/râteau.rb:2029:dans `chaque'
/Library/Ruby/Gems/1.8/gems/rake-0.8.7/lib/râteau.rb:2029:dans "le top_level'
/Library/Ruby/Gems/1.8/gems/rake-0.8.7/lib/râteau.rb:2068:dans "le standard_exception_handling'
/Library/Ruby/Gems/1.8/gems/rake-0.8.7/lib/râteau.rb:2023:dans "le top_level'
/Library/Ruby/Gems/1.8/gems/rake-0.8.7/lib/râteau.rb:2001:dans "exécuter"
/Library/Ruby/Gems/1.8/gems/rake-0.8.7/lib/râteau.rb:2068:dans "le standard_exception_handling'
/Library/Ruby/Gems/1.8/gems/rake-0.8.7/lib/râteau.rb:1998:dans "exécuter"
/Library/Ruby/Gems/1.8/gems/rake-0.8.7/bin/râteau:31
/usr/bin/râteau:19:dans la "charge"
/usr/bin/râteau:19

Vous ne savez pas où commencer dans le diagnostic de cette. Cela n'est jamais arrivé avant, et j'ai utilisé retardé d'emploi avant de sérialiser les objets de modèle, sans aucun problème. Pourquoi cette fois?

Merci à l'avance!

69voto

Michiel de Mare Points 15888

Ce n'est pas vraiment une erreur de désérialisation, c'est une erreur d'enregistrement introuvable sur ActiveRecord sur une simple requête Model.find (id).

Si vous voulez connaître les détails, connectez-les dans le fichier delayed_job-2.1.3/lib/delayed/serialization/active_record.rb , dans la déclaration de sauvetage, juste avant que le travail différé n'augmente stupidement le DeserializationError et jette les informations utiles.

12voto

Tony Points 6793

Michiel a raison. Examinez le champ de votre gestionnaire pour les objets tels que "! Ruby / ActiveRecord: YourClassName"

Vérifiez ensuite si les objets peuvent être récupérés via la clé primaire

Depuis la console, vous pouvez également tester cela en faisant quelque chose comme:

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

3voto

Harshal_m_joshi Points 426

Je crois que cela se produit lorsque vous exécutez un travail sur un objet AR non enregistré ou supprimé car la désérialisation pour AR charge l'enregistrement par identifiant. Une exception devrait probablement être levée si vous essayez de retarder une méthode sur un objet AR non enregistré.

1voto

ideaoforder Points 478

Il y a également un bogue documenté avec DJ lorsque les paramètres passés dans le gestionnaire de domaine dans la base de données sont plus longues que le TEXTE standard de la colonne:

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

Si cela arrive à être votre problème, la modification de la colonne à une MEDIUMINT devrait résoudre le problème.

Je l'ai fait en une migration de la sorte:

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

Vous pouvez vérifier pour voir si c'est un problème avec un simple DB requête:

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

1voto

spilliton Points 1025

Si quelqu'un veut faire du travail différé, il suffit de terminer le travail en tant que non-opération, vous pouvez corriger le singe avec ce code dans l'initialiseur:

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

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X