2011-02-04 9 views
13

Estoy ejecutando un trabajador de trabajos retrasados. Cuando invoco el método foo, el trabajador imprime hello.Trabajo retrasado: cómo volver a cargar las clases de carga durante cada llamada en el modo de desarrollo

class User 
    def foo 
    puts "Hello" 
    end 
    handle_asynchronously :foo 
end 

Si hago algunos cambios en el método de foo, tengo que reiniciar el trabajador para que los cambios reflejan. En el modo de desarrollo, esto puede ser bastante molesto.

Estoy tratando de encontrar una forma de volver a cargar la clase de carga útil (en este caso, la clase de usuario) para cada solicitud. Intenté el parche de mono de la biblioteca DelayedJob para invocar require_dependency antes de la invocación del método de carga.

module Delayed::Backend::Base 
    def payload_object_with_reload 
    if Rails.env.development? and @payload_object_with_reload.nil? 
     require_dependency(File.join(Rails.root, "app", "models", "user.rb")) 
    end 
    @payload_object_with_reload ||= payload_object_without_reload 
    end 
    alias_method_chain :payload_object, :reload 
end 

Este enfoque no funciona como las clases registradas usando require_dependency necesidades que volver a cargar antes de la invocación y no he encontrado la manera de hacerlo. Pasé algún tiempo leyendo el código del operador para descubrir cómo Rails vuelve a cargar las clases para cada solicitud. No pude localizar el código de recarga.

¿Alguien ha intentado esto antes? ¿Cómo me aconsejarías que proceda? ¿O tiene algún puntero para localizar el código de recarga de la clase Rails?

Respuesta

19

He logrado encontrar una solución. Usé el método ActiveSupport::Dependencies.clear para borrar las clases cargadas.

Añadir un archivo llamado config/initializers/delayed_job.rb

Delayed::Worker.backend = :active_record 
if Rails.env.development? 
    module Delayed::Backend::Base 
    def payload_object_with_reload 
     if @payload_object_with_reload.nil? 
     ActiveSupport::Dependencies.clear 
     end 
     @payload_object_with_reload ||= payload_object_without_reload 
    end 
    alias_method_chain :payload_object, :reload 
    end 
end 
+1

gracias! esto funciona muy bien, incluso con mongoid como back-end. solo tuve que eliminar la primera línea para que funcione :) –

+0

¡Agradable! se hizo algo similar pero como un [script separado] (http://stackoverflow.com/questions/1609586/rails-delayed-job-want-to-load-newest-version-of-job-class/7861250#7861250) y usarlo junto con [capataz] (http://blog.daviddollar.org/2011/05/06/introducing-foreman.html) –

+0

Realmente no entiendo * por qué * pero esto hace que la memoria de mi Rails explote en todos los entornos (incluida la producción) y las instancias que no son DJ. –

1

partir de la versión 4.0.6, DelayedJob vuelve a cargar automáticamente si es Rails.application.config.cache_classes establecido en false:

En el modo de desarrollo, si está utilizando Rails 3.1+, su código de aplicación se volverá a cargar automáticamente cada 100 trabajos o cuando la cola termine. Ya no es necesario reiniciar el trabajo diferido cada vez que actualice su código en desarrollo.

Cuestiones relacionadas