2011-02-04 10 views
13

Sto eseguendo un lavoro in ritardo. Quando invoco sempre il metodo foo, l'operatore stampa hello.Lavoro ritardato: come ricaricare le classi del payload durante ogni chiamata in modalità di sviluppo

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

Se faccio alcune modifiche al metodo di foo, devo riavviare il lavoratore per i cambiamenti per riflettere. Nella modalità di sviluppo questo può diventare piuttosto faticoso.

Sto cercando di trovare un modo per ricaricare la classe del payload (in questo caso la classe User) per ogni richiesta. Ho provato a eseguire il patching della libreria DelayedJob per richiamare require_dependency prima del richiamo del metodo del payload.

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 

Questo approccio non funziona come le classi registrate usando require_dependency necessario ricaricare prima che l'invocazione e non ho capito come farlo. Ho passato un po 'di tempo a leggere il codice del dispatcher per capire come Rails ricarica le classi per ogni richiesta. Non ero in grado di localizzare il codice di ricarica.

Qualcuno ha provato prima? Come mi consiglieresti di procedere? O hai qualche indicazione per localizzare il codice di ricarica della classe Rails?

risposta

19

Sono riuscito a trovare una soluzione. Ho usato il metodo ActiveSupport::Dependencies.clear per cancellare le classi caricate.

Aggiungere un file chiamato 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

grazie! questo funziona alla grande, anche con mongoid come backend. ho solo dovuto rimuovere la prima riga per farlo funzionare :) –

+0

Bello! è stato creato qualcosa di simile ma come [script separato] (http://stackoverflow.com/questions/1609586/rails-delayed-job-want-to-load-newest-version-of-job-class/7861250#7861250) e usalo insieme a [caposquadra] (http://blog.daviddollar.org/2011/05/06/introducing-foreman.html) –

+0

Non capisco veramente * perché * ma questo fa esplodere la memoria di Rails in tutti gli ambienti (inclusa la produzione) e le istanze non DJ. –

1

A partire dalla versione 4.0.6, DelayedJob ricarica automaticamente se è Rails.application.config.cache_classes impostato su false:

In modalità di sviluppo, se si utilizza Rails 3.1+, il codice dell'applicazione verrà ricaricato automaticamente ogni 100 lavori o al termine della coda. Non è più necessario riavviare il lavoro differito ogni volta che si aggiorna il codice in fase di sviluppo.

Problemi correlati