Domanda

Sto usando il plugin delayed_job in Rails per eseguire l'elaborazione in background e sto sperimentando un singhiozzo nello "sviluppo agile" che ho sperimentato finora in Rails ...

Di solito su rotaie se ho riscontrato un errore / voglio aggiungere alcune nuove funzionalità, aggiungo solo un po 'di codice e aggiorno la pagina e il nuovo codice viene eseguito.

Con delayed_job, sembra che la classe di lavoro non venga ricaricata ... se un lavoro fallisce e io vado a riparare l'errore e licenziare di nuovo il lavoro, il vecchio codice viene eseguito di nuovo.

Esiste un modo per fare in modo che delayed_job carichi la versione più recente della classe di lavoro prima di richiamarla?

Nel caso in cui questo abbia qualcosa a che fare con questo, so che delayed_job ha alcune opzioni diverse per dichiarare i lavori / eseguire lavori:

La mia classe di lavoro è nella directory lib di Rails ed è dichiarata come:

class FooJob < Struct.new(:foo_id)

e sto invocando il lavoro in questo modo dal controller:

Delayed::Job.enqueue(FooJob.new(params[:id]))
È stato utile?

Soluzione

Non c'è niente incorporato per fare questo. Generalmente sei responsabile della gestione e della ricarica dei tuoi lavoratori. Ciò è probabilmente altrettanto valido dal momento che il ricaricamento dello sviluppo di Rails è buono ma non perfetto, e il tentativo di ricaricare automaticamente un lavoro ritardato potrebbe potenzialmente incorrere in tutti i problemi sottili che sarebbero piuttosto opachi da debug all'interno di un processo di lavoro. Inoltre, se ricaricasse automaticamente l'ambiente per ogni lavoro, molti casi d'uso diventerebbero tremendamente lenti in modalità dev.

Il mio suggerimento è solo di abituarmi a fare lavori rake: lavoro e poi Ctrl-C quando si apportano modifiche. In alternativa è possibile creare uno script che esegua manualmente i lavori solo su base ad-hoc (tratto da delayed_job docs ):

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

Delayed::Worker.new.start  

Altri suggerimenti

Uso questo hack che funziona abbastanza bene, ma tieni presente che probabilmente è molto specifico per Rails e delayed_job, quindi probabilmente dovrai cambiare alcune cose. Testato con Rails 3.2.0 e delayed_job 2.1.4.

Metti questo in es script / delayed_job_development ed eseguilo dalla radice di 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

Per favore, commenta se sai che questa è una pessima idea o cose di cui devi essere consapevole, la uso principalmente quando modifico e collaudo i lavori che vengono eseguiti immediatamente non con lavori programmati per durare a lungo nel futuro.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top