Rails 3.1/rake - 没有队列的特定日期任务 [英] Rails 3.1/rake - datespecific tasks without queues

查看:72
本文介绍了Rails 3.1/rake - 没有队列的特定日期任务的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想让我的用户选择在特定(用户给定)时间向他们发送他们的帐户统计信息的每日摘要....

I want to give my users the option to send them a daily summary of their account statistics at a specific (user given) time ....

让我们说以下模型:

class DailySummery << ActiveRecord::Base
  # attributes:
  # send_at
  # => 10:00 (hour)
  # last_sent_at
  # => Time of the last sent summary
end

现在是否有最佳做法,如何通过电子邮件将帐户摘要发送到特定时间?

Is there now a best practice how to send this account summaries via email to the specific time?

目前我有一个无限的rake任务正在运行,它会永久检查电子邮件是否可以发送,我想将dailysummary-generation和发送放入这个rake任务中.

我有一个想法,我可以用以下伪代码解决这个问题:

I had a thought that I could solve this with following pseudo-code:

while true
  User.all.each do |u|
    u.generate_and_deliver_dailysummery if u.last_sent_at < Time.now - 24.hours
  end
  sleep 60
end

但我不确定这是否有一些隐藏的警告...

But I'm not sure if this has some hidden caveats...

注意:我不想使用像 resq 或 redis 之类的队列!

添加睡眠(已在我的脚本中)

这是一项对时间要求严格的服务(交易汇率通知),因此应该尽可能快.这就是为什么我不想使用基于队列或作业的系统的背景.我使用 Monit 来管理这个 rake 任务,效果非常好.

推荐答案

我看到了在特定时间完成任务的两种可能性.

I see two possibilities to do a task at a specific time.

后台进程/Worker/...

这是你已经完成的.我重构了你的例子,因为有两件坏事.

It's what you already have done. I refactored your example, because there was two bad things.

  1. 直接从数据库中检查条件,比加载潜在的无用数据更有效
  2. 批量加载用户.想象一下,您的数据库包含数百万用户……我很确定您会很高兴,但 Rails 不会……一点也不.:)
  1. Check conditions directly from your database, it's more efficient than loading potential useless data
  2. Load users by batch. Imagine your database contains millions of users... I'm pretty sure you would be happy, but not Rails... not at all. :)

在您的代码旁边,我看到了另一个问题.您将如何在您的生产服务器上管理此后台作业?如果您不想使用 Resque 或其他东西,您应该考虑以另一种方式管理它.有 MonitGod 都是进程监视器.

Beside your code I see another problem. How are you going to manage this background job on your production server? If you don't want to use Resque or something else, you should consider manage it another way. There is Monit and God which are both a process monitor.

while true
  # Check the condition from your database
  users = User.where(['last_sent_at < ? OR created_at IS NULL', 24.hours.ago])
  # Load by batch of 1000
  users.find_each(:batch_size => 1000) do |u|
     u.generate_and_deliver_dailysummery
  end
  sleep 60
end

Cron 作业/计划任务/...

第二种可能性是递归地安排您的任务,例如每小时或半小时.如果我错了,请纠正我,但是您的用户真的需要在上午 10:39 安排交货吗?我认为让他们选择时间就足够了.

The second possibility is to schedule your task recursively, for instance each hour or half-hour. Correct me if I'm wrong, but do your users really need to schedule the delivery at 10:39am? I think that let them choose the hour is enough.

应用这一点,我认为 每小时解雇的工作比每分钟查询数据库的无限任务要好.此外,操作起来非常简单,因为您无需进行任何设置.

Applying this, I think a job fired each hour is better than an infinite task querying your database every single minute. Moreover it's really easy to do, because you don't need to set up anything.

有一个很好的 gem 可以使用 ruby​​ 语法管理 cron 任务.更多信息在这里:每当

There is a good gem to manage cron task with the ruby syntax. More infos here : Whenever

这篇关于Rails 3.1/rake - 没有队列的特定日期任务的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆