ruby on rails - tutorial - ¿Cómo resolver el error de deserialización en el trabajo retrasado?
rails active job (6)
Estoy intentando usar DelayedJob y el trabajo está fallando, dando el siguiente error en la base de datos:
{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.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 `each'' /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
No estoy seguro por dónde empezar a diagnosticar esto. Esto nunca ha sucedido antes y he usado trabajo retrasado antes para serializar objetos modelo sin ningún problema. ¿Por qué esta vez?
¡Gracias por adelantado!
Creo que esto ocurre cuando ejecuta un trabajo contra un objeto AR no guardado o eliminado ya que la deserialización para AR carga el registro por id. Probablemente se debe lanzar una excepción si intenta retrasar un método en un objeto AR no guardado.
En realidad no es un error de deserialización, es un error de registro no encontrado de ActiveRecord en una consulta simple de Model.find (id).
Si desea conocer los detalles, delayed_job-2.1.3/lib/delayed/serialization/active_record.rb
en el delayed_job-2.1.3/lib/delayed/serialization/active_record.rb
, en la instrucción de rescate, justo antes de que el trabajo demorado DeserializationError
estúpidamente el DeserializationError
y arroje la información útil.
Hoy, también sufrí este error y después de hacer un análisis agitado encontré:
- retrayed_job convierte los métodos y parámetros al formato YAML y los almacena en la base de datos
- Se puede encontrar usando
select * from delayed_jobs
; - Se produce un error de deserialización cuando el trabajo retardado no puede deserializarlo.
Las causas probables pueden ser:
- args ["xyz"] utilizado antes de llamar a la persona retrayed_job y al interno utilizándolo como args [: xyz]
- A veces, los argumentos extra pasaron junto con el objeto a la tarea demorada en el tiempo que el trabajo demorado no puede generar el objeto, ya que es un acceso indiferente.
¡Espero que esto sea de ayuda!
Michiel tiene razón. Mire su campo de controlador para objetos como "! Ruby / ActiveRecord: YourClassName"
A continuación, compruebe si los objetos se pueden recuperar a través de la clave principal
Desde la consola también puedes probar esto haciendo algo como:
# first job in your delayed queue
YAML.load(Delayed::Backend::ActiveRecord::Job.first.handler)
Si alguien quiere hacer un trabajo retrasado, simplemente termine el trabajo como no-operativo, puede hacer un parche de mono con este código en el inicializador:
También hay un error documentado con DJ cuando los parametros pasados al campo del manejador en el DB son más largos que una columna de TEXTO estándar:
https://github.com/collectiveidea/delayed_job/issues/491
Si este es su problema, cambiar la columna a un MEDIUMINT debería solucionar el problema.
Hice esto en una migración como esta:
change_column :delayed_jobs, :handler, :text, :limit => 16777215
ActiveRecord::Base.connection.execute("DELETE FROM delayed_jobs WHERE LENGTH(handler) >= 65535")
Puede verificar si es un problema con una simple consulta DB:
SELECT * FROM delayed_jobs WHERE LENGTH(handler) >= 65535