2010-12-15 101 views
1

我正在制作一个名为“图书俱乐部”的应用程序。系统中将有很多书和票。每个月,在本月的第一天,我需要系统自动将具有最高票数的书籍推荐为“本月书”。推销一本书并确保每月只有一本书的逻辑已经实施。Rails应用程序需要每月执行一次任务

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 

而我试图让通过。

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

克朗对我的口味有点过于sl。。我想要一个更便携的解决方案。

delayed_job/Resque对于这种情况似乎有点过重。此外,我还不确定如何让他们每月运行一次工作。

只是寻找一个简单,但强大的TESTABLE解决方案。

欢呼,一如既往!

+1

如果你可以解释为什么'cron'对你来说太sl I,我可以建议更好的选择。 – Swanand 2010-12-15 04:13:41

+0

要使用cron,我必须在我的测试套件中开始做出假设。我可以完成cron作业调用并测试的rake任务,但是我仍然假定cron作业将在我的环境中设置。也许我在那个时候有点儿迂腐,但它不能覆盖这个系统的关键方面并不合适。 – drmanitoba 2010-12-15 15:37:18

回答

1

一个很好的方法来管理周期性任务是每当:https://github.com/javan/whenever

我确实使用OS的cron,但所有的配置你的生活Rails应用程序里面,所以它的更好的工作。

然而,对于维护类型的任务而言,如果出于某种原因某些原因不能在某小时的顶部运行或因某种原因而被忽略,那么这对于维护类型任务来说是非常合适的,松弛将会被接下来时间,在你的情况下,周期性的事情是任务的一部分,这是一个更强硬的呼叫。

也许应用程序可以只是“问”自己它是否是本月的第一个排名视图加载的时间,如果是,它会在适当的日期范围内仅使用投票来完成计数?

,并测试时间相关的行为,checkout出来时空特警:https://github.com/jtrupiano/timecop

+0

我曾想过在ApplicationController上用before_filter做“总是问自己”的方法,但我开始怀疑这是否会成为每次请求中不必要的资源浪费。 – drmanitoba 2010-12-15 04:15:10

0

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

0

我们在这里谈论2不同的东西:

  1. 运行并执行系统任务的作业:这将是通过rake,它是非常可靠和行之有效的。
  2. 调度程序,它根据您指定的计划运行此任务。看来你正在寻找cron的替代品。你可以试试launchd
1

我对这种类型的需求使用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 
+0

我对DJ不太熟悉。一旦我设置完成,我将如何将该任务添加到队列中? – drmanitoba 2010-12-16 03:47:20

+0

在书对象上调用一次'promote'方法,这会将作业添加到队列中。从这一点开始,这个方法将每个月调用一次。 – 2010-12-16 11:37:07

0

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

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

相关问题