Pregunta

Estoy usando el plugin delayed_job en Rails para realizar el procesamiento en segundo plano, y estoy experimentando un problema en el 'desarrollo ágil' que he experimentado hasta ahora en Rails ...

Por lo general, en los rieles si obtengo un error / deseo agregar alguna nueva funcionalidad, solo agrego un código y actualizo la página y el nuevo código se ejecuta.

Con delayed_job, parece que la clase de trabajo no se está volviendo a cargar ... si falla un trabajo y voy y soluciono el error y lo vuelvo a ejecutar, el código antiguo se ejecuta de nuevo.

¿Hay alguna forma de hacer que delayed_job cargue la versión más reciente de la clase de trabajo antes de invocarla?

En caso de que esto tenga algo que ver con esto, sé que delayedjob tiene algunas opciones diferentes para declarar trabajos / ejecutar trabajos:

Mi clase de trabajo está en el directorio lib de Rails y se declara como:

class FooJob < Struct.new(:foo_id)

y estoy invocando el trabajo así desde el controlador:

Delayed::Job.enqueue(FooJob.new(params[:id]))
¿Fue útil?

Solución

No hay nada incorporado para hacer esto. En general, usted es responsable de administrar y recargar a sus trabajadores. Probablemente esto sea igual de bueno ya que la recarga de desarrollo de Rails es buena pero no perfecta, y el intento de recargar automáticamente un trabajo retrasado podría potencialmente tener todo tipo de problemas sutiles que serían bastante opacos para depurar dentro de un proceso de trabajo. Además, si recarga automáticamente el entorno para cada trabajo, muchos casos de uso se volverían tremendamente lentos en el modo de desarrollo.

Mi sugerencia es simplemente acostumbrarse a hacer rake jobs: work y luego Ctrl-C cuando realice cambios. Alternativamente, puede crear un script que solo ejecute manualmente los trabajos de manera ad-hoc (tomado de delayed_job docs ):

#!/usr/bin/env ruby
require File.dirname(__FILE__) + '/../config/environment'

Delayed::Worker.new.start  

Otros consejos

Utilizo este truco que parece que funciona bastante bien, pero ten en cuenta que probablemente sea una versión específica de Rails y delayed_job, por lo que probablemente tengas que cambiar algunas cosas. Probado con Rails 3.2.0 y delayed_job 2.1.4.

Pon esto en, por ejemplo. script / delayed_job_development y ejecútelo desde la raíz de Rails.

#!/usr/bin/env ruby

require File.expand_path('../config/environment', File.dirname(__FILE__))
require 'delayed/worker'
require "rails/console/app"

class DummyConsoleClass
  include Rails::ConsoleMethods
end
dummy_console = DummyConsoleClass.new

worker = Delayed::Worker.new({:quiet => false})

puts "Waiting for jobs..."
loop do
  if Delayed::Job.find_available(worker.name).count > 0
    puts "Found jobs"
    dummy_console.reload!
    loop do
      break if worker.work_off.sum == 0
    end
    puts "Done, waiting for jobs..."
  end
  sleep(2)
end

Por favor, comente si sabe que esta es una muy mala idea o algo que debe tener en cuenta. Lo uso principalmente al editar y probar trabajos que se ejecutan de inmediato, no con los trabajos programados para el futuro.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top