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

发布于 2024-10-07 19:55:32 字数 1372 浏览 2 评论 0原文

我正在制作一个名为读书俱乐部的应用程序。很多有投票的书籍都会在系统中。每个月的第一天,我需要系统自动将得票数最高的书推荐为“本月图书”。推广一本书并确保本月仅存在一本书的逻辑已经实现。

book.promote!

可爱吧?

我有一个测试用例

    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 似乎有点太重了。我也有点不确定如何让他们每月运行一次工作。

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

干杯,一如既往!

I'm making an app called book club. Lots of books with votes will be in the system. Each month, on the first of the month, I need the system to automatically promote the book with the highest number of votes to be the "book of the month". The logic to promote a book and ensure only one book of the month exists has already been implemented.

book.promote!

Lovely, huh?

I have me a test case 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

And I'm trying to get that passing.

So the question is, how do I best implement an automated, once a month update that can be tested by this scenario?

Cron is a bit too sloppy for my taste. I would like a more portable solution.

delayed_job/Resque seems a bit too heavy for the situation. Also I'm a bit unsure of how to get them to run jobs once a month.

Just looking for a simple, but robust, and TESTABLE solution.

Cheers, as always!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

小情绪 2024-10-14 19:55:32

我使用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

I use delayed_job for this type of requirements.

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
爱情眠于流年 2024-10-14 19:55:32

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

我确实使用 OS cron,但所有配置都位于 Rails 应用程序内,因此使用起来更好。

然而,虽然它非常适合维护类型的任务,例如,如果由于某种原因某些东西没有在整点运行或由于某种原因被跳过,那么下一次就会在你的系统中弥补这一不足。如果周期性的事情是任务的一部分,那么这是一个更艰难的决定。

也许应用程序可以“总是”问自己,当排名视图加载时,它是否是当月的第一天,如果是,它会只使用适当日期范围内的投票来进行统计?

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

A nice way to manage periodic tasks is with whenever: https://github.com/javan/whenever

I does use OS cron, but all the config lives inside your rails app, so it's nicer to work with.

However, while it's quite appropriate for maintenance type tasks where, say, if for some reason something doesn't run exactly at the top of the hour or gets skipped over for some reason, the slack will be picked up the next time, in your case where the periodic thing is part of the task, it's a tougher call.

Maybe the app can just "always" ask itself if it's the first of the month yet when the rankings view loads, and if it is, it will do the tally, using only votes within the appropriate date range?

And to test time-dependent behavior, checkout out timecop: https://github.com/jtrupiano/timecop

飘过的浮云 2024-10-14 19:55:32

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

As John started to say Cron/whenever is the way to go here. Other background daemons require a separate process that will be idle most of the time. You shouldn't have any portability issues with cron unless you're concerned about running on Windows.

花海 2024-10-14 19:55:32

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

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

We are talking about 2 different things here:

  1. A job that runs and performs task for the system: That would be through rake, it is pretty reliable and well tested.
  2. A scheduler, which runs this task on a schedule you specify. It seems you are looking for alternatives to cron. You can try launchd for this.
虐人心 2024-10-14 19:55:32

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

当您的应用程序扩展时,您将希望在单独的工作进程中运行此计算,以减少对用户体验的影响。 Delayed_job 一石二鸟:提供调度机制,并将promote 计算卸载到单独的工作进程。

delayed_job is really a good choice. You are currently testing with a small number of books, so the promote calculation is done fairly quickly.

When your app scales, you will want to run this calculation in a separate worker process to reduce the impact on the User Experience. delayed_job will kill two birds with one stone: provide a scheduling mechanism and offload the promote calculation to a separate worker process.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文