Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/ruby/24.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ruby on rails Rails 3.1/rake-不带队列的日期特定任务_Ruby On Rails_Ruby_Ruby On Rails 3_Rake_Scheduled Tasks - Fatal编程技术网

Ruby on rails Rails 3.1/rake-不带队列的日期特定任务

Ruby on rails Rails 3.1/rake-不带队列的日期特定任务,ruby-on-rails,ruby,ruby-on-rails-3,rake,scheduled-tasks,Ruby On Rails,Ruby,Ruby On Rails 3,Rake,Scheduled Tasks,我想给我的用户一个选项,让他们在特定的(用户指定的)时间向他们发送帐户统计的每日摘要 让我们假设以下模型: class DailySummery << ActiveRecord::Base # attributes: # send_at # => 10:00 (hour) # last_sent_at # => Time of the last sent summary end 课堂每日总结10:00(小时) #上次发送时间 #=>上次发送摘要的时间

我想给我的用户一个选项,让他们在特定的(用户指定的)时间向他们发送帐户统计的每日摘要

让我们假设以下模型:

class DailySummery << ActiveRecord::Base
  # attributes:
  # send_at
  # => 10:00 (hour)
  # last_sent_at
  # => Time of the last sent summary
end
课堂每日总结10:00(小时)
#上次发送时间
#=>上次发送摘要的时间
结束
现在是否有最佳实践,如何通过电子邮件将此帐户摘要发送到特定时间

目前,我有一个无限的rake任务正在运行,它会永久性地检查电子邮件是否可以发送,我想将每日摘要生成和发送放在这个rake任务中。

我想我可以用以下伪代码来解决这个问题:

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
为true时
User.all.each do|u|
u、 如果上次发送时间
但我不确定这是否有一些隐藏的警告

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

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


编辑:这是一项时间紧迫的服务(交易价格通知),因此应该尽可能快。这就是为什么我不想使用基于队列或作业的系统的背景。我使用Monit来管理这个rake任务,它工作得非常好。

只有两种主要方法可以延迟执行。当站点上的用户点击某个页面时运行脚本,这样做效率低且不完全准确。或者使用某种后台进程,无论是cron作业还是resque/delayed作业等

虽然让rake进程永远运行的方法可以很好地工作,但效率很低,因为一旦完成,您就要24/7地对用户进行迭代,比如:

while true
    User.where("last_sent_at <= ? OR last_sent_at = ?", 24.hours.ago, nil).each do |u|
            u.generate_and_deliver_dailysummery
    end

    sleep 3600
end
为true时

User.where(“last_sent_at实际上只有两种主要方法可以执行延迟执行。当站点上的用户点击页面时运行脚本,这是低效且不完全准确的。或者使用某种后台过程,无论是cron作业还是resque/延迟作业/等等

虽然让rake进程永远运行的方法可以很好地工作,但效率很低,因为一旦完成,您就要24/7地对用户进行迭代,比如:

while true
    User.where("last_sent_at <= ? OR last_sent_at = ?", 24.hours.ago, nil).each do |u|
            u.generate_and_deliver_dailysummery
    end

    sleep 3600
end
为true时

User.where(“last_sent_at您可以这样做,您还需要检查您要发送的时间。因此,从伪代码开始并添加到伪代码:

while true
  User.all.each do |u|
    if u.last_sent_at < Time.now - 24.hours && Time.now.hour >= u.send_at
      u.generate_and_deliver_dailysummery
      # the next 2 lines are only needed if "generate_and_deliver_dailysummery" doesn't sent last_sent_at already
      u.last_sent_at = Time.now  
      u.save
    end
  end

  sleep 900
end
为true时
User.all.each do|u|
如果上次发送时间=u.send\u在
u、 生成和交付每日摘要
#仅当“generate_and_deliver_dailysummery”尚未在最后发送时才需要下两行
u、 上次发送时间=Time.now
u、 拯救
结束
结束
睡900
结束

我还添加了
sleep
,这样您就不会不必要地重击数据库。您可能还想研究将循环限制在您需要发送给的一组用户。类似于Zachary建议的查询将比您现有的查询效率更高。

您可以这样做,还需要检查您想要使用的时间从伪代码开始并添加到它:

while true
  User.all.each do |u|
    if u.last_sent_at < Time.now - 24.hours && Time.now.hour >= u.send_at
      u.generate_and_deliver_dailysummery
      # the next 2 lines are only needed if "generate_and_deliver_dailysummery" doesn't sent last_sent_at already
      u.last_sent_at = Time.now  
      u.save
    end
  end

  sleep 900
end
为true时
User.all.each do|u|
如果上次发送时间=u.send\u在
u、 生成和交付每日摘要
#仅当“generate_and_deliver_dailysummery”尚未在最后发送时才需要下两行
u、 上次发送时间=Time.now
u、 拯救
结束
结束
睡900
结束

我还添加了
sleep
,这样您就不会不必要地重击数据库。您可能还想研究将该循环限制为仅限于您需要发送到的用户集。类似于Zachary建议的查询将比您现有的查询效率更高。

定期运行任务是cron的作用所在。the gem(https://github.com/javan/whenever)使为应用程序配置cron定义变得简单


随着应用程序的扩展,您可能会发现rake任务的运行时间太长,而且队列在cron调度上非常有用。您可以使用cron控制何时调度交付,但实际由工作池执行交付。

cron的作用是定期运行任务(https://github.com/javan/whenever)使为应用程序配置cron定义变得简单


作为应用程序的比例,您可能会发现RAKE任务运行时间过长,队列在CRON调度之上是有用的。您可以使用CRON来控制交付时的调度,但实际上是由一个工作池执行的。

< P>如果您不想使用队列-考虑延迟作业(排序为一个可怜的MAN队列)-它确实作为一个类似于您正在做的rake任务运行

它将所有任务存储在作业表中,通常在您添加任务时,它会将其排队以尽快运行,但是您可以覆盖它以将其延迟到特定时间


您可以将DayLyPrimeCype转换为DayySyryYeWork,一旦完成,它可以在下一天运行中重新排队自己的实例

如果您不想使用队列——考虑延迟作业(排序为一个穷人队列)-它运行的RAKE任务类似于您正在做的

它将所有任务存储在作业表中,通常在您添加任务时,它会将其排队以尽快运行,但是您可以覆盖它以将其延迟到特定时间


您可以将DailySummary类转换为DailySummary作业,一旦完成,它就可以为自己的新实例重新排队,以便在接下来的几天运行

您是如何更新
last\u sent\u at
属性的

如果你使用

last_sent_at += 24.hours  
并初始化为
last\u sent\u at=Time.now.at\u开始日期+send\u at

一切都会好起来的

不要在=时间使用上次发送。现在使用。这是bec