rufus-планировщик не планирует при запуске поверх Rails+Unicorn в отдельном режиме

Я использую rufus-планировщик для планирования некоторых работ в моем приложении Ruby on Rails. Соответствующие спецификации:

  • Рубин: 2.1.2p95
  • Рельсы: 4.1.1
  • Руфус-Планировщик: 3.0.9

Планировщик работает отлично, когда я запускаю приложение с помощью "rails s unicorn". Однако, когда я отсоединяю сервер с помощью опции -d, запланированные задания никогда не запускаются.

Вот мой файл config/initializers/task_scheduler.rb:

require 'rubygems'
require 'rufus/scheduler'
require 'rake'

load File.join(Rails.root, 'lib', 'tasks', 'send_emails.rake')
MyApplication::Application.load_tasks
scheduler = Rufus::Scheduler.new(:lockfile => ".rufus-scheduler.lock")

if (!MyApplication.rake?)
  unless scheduler.down?

    Rails.logger.info "OK"

    scheduler.interval("1m") do
      Rails.logger.info "yup"
      system ("rake send_emails:mail_users")
    end 

  end
end

и мой файл unicorn.rb:

worker_processes 2
preload_app true
timeout 30

before_fork do |server, worker|
  Signal.trap 'TERM' do
    puts 'Unicorn master intercepting TERM and sending myself QUIT instead'
    Process.kill 'QUIT', Process.pid
  end

  defined?(ActiveRecord::Base) and
    ActiveRecord::Base.connection.disconnect!
end

after_fork do |server, worker|
  Signal.trap 'TERM' do
    puts 'Unicorn worker intercepting TERM and doing nothing. Wait for master to send QUIT'
  end

  defined?(ActiveRecord::Base) and
    ActiveRecord::Base.establish_connection
end

"!MyApplication.rake?" строка предназначена для предотвращения запуска планировщиком задач rake; Я добавил эту строку в мой Rakefile:

MyApplication.rake = true

Когда я просматриваю свой журнал, я замечаю, что печатается строка "ОК", поэтому я считаю, что планировщик инициализируется правильно, но строка регистратора для задания никогда не печатается и задача rake не запускается.

На данный момент я не уверен, заключается ли проблема в моей конфигурации единорога или в конфигурации планировщика. Любая помощь будет принята с благодарностью!

редактировать 1:

Вывод журнала от "rails s"

I, [2015-01-28T20:11:05.179505 #79141]  INFO -- : listening on addr=0.0.0.0:3000 fd=12
Before
Before
I, [2015-01-28T20:11:05.426386 #79141]  INFO -- : master process ready
After
After
I, [2015-01-28T20:11:05.434392 #79143]  INFO -- : worker=0 ready
I, [2015-01-28T20:11:05.435585 #79144]  INFO -- : worker=1 ready
yup

Вывод журнала от "rails s -d"

OK
Before
Before
After
After

Как предположил jmettraux, при использовании опции "-d" планировщик теряется после разветвления. Я немного переключился, переместил планировщик в класс и вызвал инициализатор из блока after_fork:

Библиотека / scheduler.rb

require 'rufus/scheduler'
class Scheduler

  def self.startup
    Rails.logger.info "startup"
    load File.join(Rails.root, 'lib', 'tasks', 'send_emails.rake')
    USA::Application.load_tasks
    scheduler = Rufus::Scheduler.new(:lockfile => ".rufus-scheduler.lock")

    if (!USA.rake?)
      Rails.logger.info "nope"
      unless scheduler.down?
        Rails.logger.info "OK"

        scheduler.interval("1m") do
          Rails.logger.info "yup"
          system ("rake send_emails:mail_users")
        end

        scheduler.join

      end
    end
  end

end

unicorn.rb:

worker_processes 2
preload_app true
timeout 100

load File.join(Rails.root, 'lib', 'scheduler.rb')

...

after_fork do |server, worker|
  Rails.logger.info "After"
  Signal.trap 'TERM' do
    puts 'Unicorn worker intercepting TERM and doing nothing. Wait for master to send QUIT'
  end

  defined?(ActiveRecord::Base) and
    ActiveRecord::Base.establish_connection

  Scheduler::startup

end

Тем не менее, это выходит из-под контроля при запуске "rails s -d", и рабочие постоянно появляются и убиваются:

Before
Before
After
After
startup
startup
Before
After
Before
startup
After
startup
Before
After
startup

Я уверен, что моя реализация запуска планировщика из блока after_fork, вероятно, виновата, но я точно не знаю, что является причиной этого.

редактировать 2

Я тупой. Я использовал суть, которую связал jmettraux, но я убил ее, когда пытался заставить ее работать в моем приложении. Я вернулся и запустил мой unicorn.rb и scheduler.rb с нуля, и теперь он работает!

1 ответ

Решение

Вы должны добавить несколько Rails.logger.info("XXX") в блок after_fork, чтобы увидеть, происходит ли это до OK или после него.

Кажется, у кого-то была такая же проблема, и она что-то придумала: https://gist.github.com/jkraemer/3851917 Ей четыре года, но она может вдохновить вас.

"Суть" этого в том, чтобы запустить / запустить rufus-scheduler в блоке after_fork (чтобы его поток не был уничтожен в форке).

Другие вопросы по тегам