关于ruby on rails:如何在Heroku上安排“每周”工作?

How can I schedule a 'weekly' job on Heroku?

我在Heroku上部署了一个带有Heroku调度器插件的Rails应用程序,成功地为日常工作工作工作。

现在我想要一份每周的工作,但是调度器插件不允许我选择每周工作。

关于如何实现这一目标的任何建议:

  • 我以前尝试过使用rufus调度程序,但它给我带来了一些问题,所以这不是一个选项。详情请参阅此处。
  • 我在考虑在日常工作中检查当天的情况。是否有人尝试过,并且对该方法有反馈或知道问题?
  • 其他想法很受欢迎。

一种方法是你的第二个要点:

激活heroku cron加载项,并在app/lib/tasks中添加cron.rake任务

激活heroku调度程序加载项,并在app/lib/tasks中添加一个scheduler.rake任务。

1
2
3
4
5
task :your_weekly_task=> :environment do
  if Time.now.friday? # previous answer: Date.today.wday == 5
    #do something
  end
end

你甚至可以奢侈地定义你想要完成任务的日期;o)(五是星期五)

编辑:顺便说一句,cron被否决了,Heroku建议切换到他们的调度程序插件。但这并不能改变每周工作的方式。

编辑2:根据沉没公司的反馈调整我的答案。


仅使用外壳代码的备用选项。每小时设置Heroku调度程序,并与日期命令进行比较:

1
2
3
# setting the schedular to run hourly at *:30 is equivalent to the
# crondate: 30 8 * * 1
if ["$(date +%H)" = 08 ] && ["$(date +%d)" = 01 ]; then YOUR_COMMAND ; fi

我用这段代码来模拟本地时区的cron:

1
nz_hour="$(TZ=NZ date +%H)" ; nz_day="$(TZ=NZ date +%d)" ; if ["$nz_hour" = 08 ] && ["$nz_day" = 01 ]; then YOUR_COMMAND ; fi


这并不理想,但我已经开始添加run-vif环境变量,通过heroku:scheduler运行rake任务,它允许我每周和每月安排作业。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
# lib/tasks/scheduler.rake
def run?
  eval ENV.fetch('RUN_IF', 'true')
end

def scheduled
  if run?
    yield
  else
    puts"RUN_IF #{ENV['RUN_IF'].inspect} eval'd to false: aborting job."
  end
end

# lib/tasks/job.rake
task :job do
  scheduled do
    # ...
  end
end

如果rake任务在没有run的情况下运行,那么它将运行。否则,除非run的值eval为假值,否则作业将中止。

1
2
3
4
$ rake job                              # => runs always
$ rake job RUN_IF='Date.today.monday?'  # => only runs on Mondays
$ rake job RUN_IF='Date.today.day == 1' # => only runs on the 1st of the month
$ rake job RUN_IF='false'               # => never runs (not practical, just demonstration)

类似于上面的其他想法,但我更喜欢将调度细节从应用程序代码中移出。


正如前面讨论的,使用Rob的上述逻辑,这里是按一周中的一天、每月一次和特定日期细分的bash脚本。

每周一运行一个任务:

1
if ["$(date +%u)" = 1 ]; then MY_COMMAND; fi

每月第一天运行一个任务:

1
if ["$(date +%d)" = 01 ]; then MY_COMMAND; fi

您还可以在每年12月24日运行一个作业:

1
if ["$(date +%m)" = 12 ] && ["$(date +%d)" = 24 ]; then MY_COMMAND; fi


如果您不想或不能使用rake完成此操作,另一个选项是使用bash中的ruby:

1
2
3
4
5
6
#!/bin/bash

cmd="echo your schedule job here"

# Only run on even days
ruby -e 'if Time.now.utc.day.even?; puts"Not today!"; exit 1; end' && $cmd"$@"

这甚至适用于非Ruby项目(如我的例子:Clojure)。