Rake任务和rails初始化器

hai*_*der 2 rake ruby-on-rails initializer rufus-scheduler

有点Rails的新手,所以请对付我.我现在正在做的是后台处理一些Ruby代码使用Resque.为了启动Rescque rake任务,我一直在使用(在heroku上),我有一个resque.rake文件,其中推荐的代码附加到heroku的神奇(或奇怪)线程架构中:

require "resque/tasks"
require 'resque_scheduler/tasks'

task "resque:setup" => :environment do
  ENV['QUEUE'] = '*'
end


desc "Alias for resque:work (To run workers on Heroku)"
task "jobs:work" => "resque:work"
Run Code Online (Sandbox Code Playgroud)

由于我需要访问Rails代码,因此我引用:environment.如果我在heroku的后台设置至少1个工作dyno,我的Resque做得很好,被清除,一切都很开心.直到我尝试自动化东西......

所以我想要进化代码并每分钟左右自动填充相关任务的队列.这样做(不使用cron,因为heroku不适合cron),我声明了一个名为task_scheduler.rb的初始化程序,它使用Rufus调度程序来运行任务:

scheduler = Rufus::Scheduler.start_new

scheduler.in '5s' do
  autoprocessor_method
end

scheduler.every '1m' do
  autoprocessor_method
end
Run Code Online (Sandbox Code Playgroud)

事情看起来有点令人敬畏......然后rake进程就不再无法解决地从队列中恢复过来了.队列越来越大.即使我有多个工作人员dynos在运行,他们最终都会感到疲倦并停止处理队列.我不确定我做错了什么,但我怀疑在我的rake任务中引用Rails环境导致task_scheduler.rb代码再次运行,导致重复调度.我想知道如果有人知道如何解决这个问题,我也很好奇,如果这是rake任务停止工作的原因.

谢谢

Mau*_*res 5

您不应该在初始化程序中启动调度程序,您应该有一个运行调度程序的守护程序进程并填满您的队列.它会是这样的("脚本/调度程序"):

#!/usr/bin/env ruby

root = File.expand_path(File.join(File.dirname(__FILE__), '..'))
Dir.chdir(root)

require 'rubygems'
gem 'daemons'
require 'daemons'

options = {
    :dir_mode   => :normal,
    :dir        => File.join(root, 'log'),
    :log_output => true,
    :backtrace  => true,
    :multiple   => false
}

Daemons.run_proc("scheduler", options) do

  Dir.chdir(root)
  require(File.join(root, 'config', 'environment'))

  scheduler = Rufus::Scheduler.start_new

  scheduler.in '5s' do
    autoprocessor_method
  end

  scheduler.every '1m' do
    autoprocessor_method
  end

end
Run Code Online (Sandbox Code Playgroud)

您可以将此脚本称为应用程序中的常用守护程序:

script/scheduler start
Run Code Online (Sandbox Code Playgroud)

这将确保您只有一个进程为resque worker发送工作,而不是为您正在运行的每个mongrel发送一个进程.