繁体   English   中英

Rake任务和rails初始化器

[英]Rake tasks and rails initializers

有点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"

由于我需要访问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

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

谢谢

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

#!/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

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

script/scheduler start

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

首先,如果你没有在Heroku上运行,我不会推荐这种方法。 我会看看Mauricio的答案,或考虑使用经典的cron作业或使用Whenever安排cron作业。

但是如果你在heroku上运行并努力做到这一点,那么我就是这样做的。

我保留了相同的原始Resque.rake代码,因为我粘贴在原始问题中。 另外,我创建了另一个附加到作业的rake任务:work rake过程,就像第一种情况一样:

desc "Scheduler processor"
  task :scheduler => :environment do
  autoprocess_method
  scheduler = Rufus::Scheduler.start_new
  scheduler.every '1m' do
     twitter_autoprocess
  end
end

desc "Alias for resque:work (To run workers on Heroku)"
task "jobs:work" => "scheduler"

几个笔记:

  1. 一旦您使用多个工作器dyno,这将是不完美的,因为调度程序将在多个位置运行。 你可以通过在某个地方保存状态来解决这个问题,但它并不像我想的那样干净。
  2. 我找到了原因导致该过程挂起的原因。 就是这行代码:

     scheduler.in '5s' do autoprocessor_method end 

    我不知道为什么,但是当我删除它时,它再也没有挂起。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM