我正在使用rufus-scheduler在我的Ruby on Rails应用程序中安排一些工作。相关规格:
当我使用" 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?" line是为了防止rake任务也运行调度程序;我已将此行添加到我的Rakefile中:
MyApplication.rake = true
当我查看我的日志时,我注意到" OK"正在打印行,所以我认为调度程序正在初始化,但是从不打印作业的记录器行并且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"时,调度程序似乎在fork之后丢失了。选项。我把调度程序移到了一个类中,并从after_fork块中调用了初始化程序:
LIB / 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链接的gist,但是当我试图让它在我的应用程序中工作时,我将其剔除了。我回去从头开始启动unicorn.rb和scheduler.rb,它现在正在工作!答案 0 :(得分:2)
你应该在after_fork块中添加一些Rails.logger.info(" XXX")以查看它是在OK之前还是之后发生。
似乎有人遇到了同样的问题并提出了一些建议:https://gist.github.com/jkraemer/3851917 它已经四岁了,但它可以给你一些启发。
"要点"它似乎是在after_fork块中运行/启动rufus-scheduler(这样它的线程就不会在fork中被杀死)。