Rails应用程序需要每月执行一次任务

时间:2010-12-15 03:15:01

标签: ruby-on-rails ruby testing cucumber

我正在制作一款名为读书俱乐部的应用。很多有投票的书都会在系统中。每个月,在本月的第一天,我需要系统自动推销具有最高票数的书作为“本月的书”。推广一本书并确保只存在一本月中的一本书的逻辑已经实施。

book.promote!

可爱,是吗?

我有一个测试用例hurr

    Given the following books exist:
  | title               | author            | year_published | votes | created_at        |
  | Lord of the Flies   | William Golding   | 1954           | 18    | January 12, 2010  |
  | The Virgin Suicides | Jeffrey Eugenides | 1993           | 12    | February 15, 2010 |
  | Island              | Richard Laymon    | 1991           | 6     | November 22, 2009 |
And the book "Lord of the Flies" is the current book of the month
And the date is "February 24, 2010"
Then the book "Lord of the Flies" should be the current book of the month
When the date is "March 1, 2010"
And I am on the home page
Then I should see "This Month's Book of the Month Club Book"
And I should see "The Virgin Suicides"
And the book "The Virgin Suicides" should be the current book of the month
And the book "Lord of the Flies" should not be the current book of the month
And the book "Island" should not be the current book of the month

我正试图通过。

所以问题是,如何最好地实现每月一次的自动更新,可以通过这种情况进行测试?

Cron对我的口味有点过于草率。我想要一个更便携的解决方案。

delayed_job / Resque似乎有点太重了。另外,我有点不确定如何让他们每个月做一次工作。

只是寻找一个简单但强大且可测试的解决方案。

干杯,一如既往!

5 个答案:

答案 0 :(得分:2)

我将delayed_job用于此类要求。

class Book
  def promote
    # code for the promote method..

  ensure
    # re-run the task in another 30 days.
    promote
  end
  # Date.today.nextmonth.beginning_of_month will be evaluated 
  #when promote is called
  handle_asynchronously :promote, :run_at => Proc.new { 
    Date.today.next_month.beginning_of_month 
  }

end

答案 1 :(得分:1)

管理周期性任务的一个好方法是随时随地:https://github.com/javan/whenever

我确实使用了OS cron,但所有配置都存在于rails应用程序中,因此使用起来更好。

然而,虽然它非常适合于维护类型的任务,例如,如果由于某种原因某些事情不能在一小时内完全运行或由于某种原因而被跳过,那么下一次就会发现松弛,在你的情况下,周期性的事情是任务的一部分,这是一个更艰难的电话。

也许应用程序可以“总是”问自己,如果它是当月的第一个但排名视图加载时,如果是,它将执行计数,仅使用适当日期范围内的投票?

要测试与时间相关的行为,请查看timecop:https://github.com/jtrupiano/timecop

答案 2 :(得分:0)

约翰开始说Cron /什么时候去这里。其他后台守护进程需要一个单独的进程,大部分时间都处于空闲状态。除非您担心在Windows上运行,否则不应该与cron有任何可移植性问题。

答案 3 :(得分:0)

我们在这里谈论两件不同的事情:

  1. 为系统运行并执行任务的作业:这将通过rake,它非常可靠且经过充分测试。
  2. 调度程序,按您指定的计划运行此任务。看来你正在寻找cron的替代品。您可以尝试使用launchd

答案 4 :(得分:0)

delayed_job真是个不错的选择。您目前正在使用少量书籍进行测试,因此promote计算相当快。

当您的应用扩展时,您需要在单独的工作进程中运行此计算,以减少对用户体验的影响。 delayed_job将一举两得:提供一个调度机制并将promote计算卸载到一个单独的工作进程。