Rake 任务和 Rails 初始化程序
对 Rails 有点陌生,所以请配合我。我现在正在做的是使用 Resque 后台处理一些 Ruby 代码。为了启动 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 代码,我参考:环境。如果我在 Heroku 的后台设置至少 1 个 Worker 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 进程就停止了莫名其妙地从队列中拿起。队列变得越来越大。即使我有多个工作测功机在运行,它们最终都会感到疲倦并停止处理队列。我不确定我做错了什么,但我怀疑在我的 rake 任务中引用 Rails 环境导致 task_scheduler.rb 代码再次运行,从而导致重复调度。我想知道如果有人知道如何解决这个问题,而且我也很好奇这是否是 rake 任务停止工作的原因。
谢谢
Kinda new to Rails, so please cope with me. What i'm doing now is background processing some Ruby code use Resque. To get the Rescque rake task started, I've been using (on heroku), I have a resque.rake file with that recommended code to attach into heroku's magical(or strange) threading architecture:
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"
Since I need access to the Rails code, I reference :environment. If I set at least 1 worker dyno in the background on heroku, my Resque does great, gets cleared, everything is happy. Until i try to automate stuff...
So I wanted to evolve the code and automatically fill the queue with relevant tasks every minute or so. Do that (without using cron, because heroku is not adequate with cron), I declare an initializer named task_scheduler.rb that uses Rufus scheduler to run tasks:
scheduler = Rufus::Scheduler.start_new
scheduler.in '5s' do
autoprocessor_method
end
scheduler.every '1m' do
autoprocessor_method
end
Things appear to work awesome for a while....then the rake process just stops picking up from the queue unexplainably. The queue just gets larger and larger. Even if i have multiple worker dynos running, they all eventually get tired and stop processing the queue. I'm not sure what I am doing wrong, but I suspect the referencing of the Rails environment in my rake task is causing the task_scheduler.rb code to run again, causing duplicate scheduling. I'm wondering how to solve that problem if someone knows, and I'm also curious if that is the reason for the rake task to stop working.
Thank you
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
您不应该在初始化程序中启动调度程序,您应该有一个守护进程运行调度程序并填充队列。它会是这样的(“脚本/调度程序”):
您可以从您的应用程序中将此脚本作为常用守护进程调用:
这将确保您只有一个进程为该应用程序发送工作resque 工作人员,而不是为您运行的每个杂种工作人员分配一个工作人员。
You should not be booting the scheduler in an initializer, you should have a daemon process running the scheduler and filling up your queue. It would be something like this ("script/scheduler"):
And you can call this script as a usual daemon from your app:
This is going to make sure you have only one process sending work for the resque workers instead of one for each mongrel that you're running.
首先,如果你不是在 Heroku 上运行,我不会推荐这种方法。我会看看 Mauricio 的答案,或者考虑使用经典的 cron 作业或使用 Everytime 来安排 cron 作业。
但如果你在 Heroku 上运行并尝试这样做时感到痛苦,那么我是如何让它发挥作用的。
我保留了相同的原始 Resque.rake 代码,就像我粘贴在原始问题中一样。此外,我创建了另一个附加到 jobs:work rake 进程的 rake 任务,就像第一种情况一样:
注意事项:
我找到了进程挂起的原始原因。就是这行代码:
我不知道为什么,但是当我删除它时,它再也没有挂起。
First of all, if you are not running on Heroku, i would not recommend this approach. I'd look at Mauricio's answer, or consider using a classic cron job or using Whenever to schedule the cron job.
But if you are in the pain of running on heroku and trying to do this, here is how i got this to work.
I kept the same original Resque.rake code in place, as i pasted in the original question. In addition, i created another rake task that i attached to the jobs:work rake process, just like the first case:
Couple of notes:
I found the original reason why the process would hang. It was this line of code:
I'm not sure why, but when I removed that, it never hung again.