Rails / delayed_job - хотите загрузить самую новую версию класса задания
Я использую плагин delayed_job в Rails для фоновой обработки, и я испытываю сбой в "гибкой разработке", которую я до сих пор испытывал в Rails...
Обычно в rails, если я сталкиваюсь с ошибкой / хочу добавить некоторые новые функции - я просто добавляю некоторый код и обновляю страницу, и новый код запускается.
При использовании delayed_job создается впечатление, что класс задания не перезагружается... если задание не выполняется, и я иду и исправляю ошибку и снова запускаю задание, старый код запускается снова.
Есть ли способ заставить delayed_job загрузить новейшую версию класса задания перед его вызовом?
На всякий случай это как-то связано с этим - я знаю, что у delayed_job есть несколько различных опций в способах объявления заданий / запуска заданий:
Мой класс заданий находится в каталоге lib Rails и объявлен так:
class FooJob < Struct.new(:foo_id)
и я вызываю задание, как это из контроллера:
Delayed::Job.enqueue(FooJob.new(params[:id]))
2 ответа
Там нет ничего встроенного, чтобы сделать это. Как правило, вы несете ответственность за управление и перезагрузку своих работников. Это, вероятно, также хорошо, так как перезагрузка разработки Rails хороша, но не идеальна, и попытка автоматической перезагрузки отложенного задания потенциально может столкнуться с тонкими проблемами всех видов, которые будут довольно непрозрачны для отладки внутри рабочего процесса. Кроме того, если бы он автоматически перезагружал среду для каждой работы, многие варианты использования были бы чрезвычайно медленными в режиме разработки.
Мое предложение просто привыкнуть делать rake jobs:work
а потом Ctrl-C
когда вы делаете изменения. В качестве альтернативы вы можете создать сценарий, который просто вручную запускает задания на временной основе (взяты из документов delayed_job):
#!/usr/bin/env ruby
require File.dirname(__FILE__) + '/../config/environment'
Delayed::Worker.new.start
Я использую этот хак, который выглядит довольно неплохо, но имейте в виду, что он, вероятно, очень специфичен для Rails и delayed_job, поэтому вам, вероятно, придется изменить некоторые вещи. Протестировано с Rails 3.2.0 и delayed_job 2.1.4.
Поместите это, например, в script/delayed_job_development
и запустить его из корня 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
Пожалуйста, прокомментируйте, если вы знаете, что это очень плохая идея или вещи, о которых нужно знать, я в основном использую их при редактировании и тестировании заданий, которые запускаются немедленно, а не заданий, запланированных на долгое время в будущем.