Rails / delay_job - veut charger la dernière version de la classe de travail
-
05-07-2019 - |
Question
J'utilise le plug-in delay_job dans Rails pour effectuer le traitement en arrière-plan et je rencontre un hoquet dans le "développement agile" que j'ai connu jusqu'à présent dans Rails ...
Habituellement, dans les rails, si je rencontre une erreur / souhaite ajouter une nouvelle fonctionnalité, il me suffit d'ajouter du code, d'actualiser la page et de faire en sorte que le nouveau code s'exécute.
Avec delay_job, il semble que la classe de travail ne soit pas rechargée ... si un travail échoue et que je corrige l'erreur et que je relance le travail, l'ancien code est exécuté à nouveau.
Existe-t-il un moyen quelconque de faire en sorte que la commande la plus récente de la classe de travaux soit chargée avec delay_job avant de l'invoquer?
Juste au cas où cela aurait quelque chose à voir avec cela - je sais que delay_job propose différentes manières de déclarer / exécuter des travaux:
Ma classe de travaux se trouve dans le répertoire lib de Rails et est déclarée comme suit:
class FooJob < Struct.new(:foo_id)
et j'appelle le travail comme celui-ci à partir du contrôleur:
Delayed::Job.enqueue(FooJob.new(params[:id]))
La solution
Il n'y a rien d'intégré pour faire cela. En général, vous êtes responsable de la gestion et du rechargement de vos travailleurs. C’est probablement tout aussi bien puisque le rechargement du développement de Rails est bon mais pas parfait, et tenter de recharger automatiquement une tâche retardée risquerait de se heurter à toutes sortes de problèmes subtils qui seraient assez opaques pour déboguer dans un processus de travail. De plus, si l'environnement rechargé automatiquement pour chaque travail, de nombreux cas d'utilisation deviendraient extrêmement lents en mode dev.
Je suggère simplement de prendre l'habitude de faire des tâches de travail du rake: travail
, puis Ctrl-C
lorsque vous apportez des modifications. Vous pouvez également créer un script qui exécute manuellement les travaux sur une base ad-hoc (extrait de docs delay_job ):
#!/usr/bin/env ruby
require File.dirname(__FILE__) + '/../config/environment'
Delayed::Worker.new.start
Autres conseils
J'utilise ce hack qui semble fonctionner assez bien, mais sachez qu'il est probablement très spécifique à la version Rails et delay_job, vous devez donc probablement changer certaines choses. Testé avec Rails 3.2.0 et delay_job 2.1.4.
Mettez ceci dans par exemple script / delay_job_development
et exécutez-le à partir de la racine 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
Veuillez commenter si vous savez que c'est une très mauvaise idée ou des choses dont il faut être conscient, je l'utilise principalement lors de l'édition et du test de tâches qui s'exécutent immédiatement et non avec des tâches planifiées pour une longue durée.