如何在Heroku上安排“每周”工作?

我在Heroku上部署了一个Rails应用程序,Heroku调度程序附加组件成功地用于日常工作。

现在我想要一份每周工作 ,但是调度程序加载项不允许我每周一次选择。

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

  • 我过去曾尝试过使用rufus-scheduler,但它给我带来了一些问题,所以这不是一个选择。 详情请见此处 。
  • 我正在考虑在日常工作中检查当天的事情。 有没有人尝试过,并有反馈或知道该方法的问题?
  • 其他想法非常感谢。

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

激活Heroku cron加载项,并在app/lib/tasks添加cron.rake app/lib/tasks

激活Heroku调度程序加载项,并在app/lib/tasks添加scheduler.rake app/lib/tasks

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

你甚至可以奢侈地定义你希望你的任务运行的那一天; o)(5是星期五)

编辑:顺便说一句,Cron已被弃用,Heroku建议切换到他们的Scheduler插件。 这并不会改变每周工作的方法。

EDIT2:根据sunkencity的反馈调整我的答案。

仅使用shell代码的备用选项。 每小时设置Heroku调度程序,并对date命令进行比较:

 # 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:

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

这不是理想的,但我已经开始添加一个RUN_IF环境变量来执行通过heroku运行的任务:scheduler,它允许我每周和每月安排作业。

 # 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 

如果在没有RUN_IF变量的情况下运行rake任务,它将运行。 否则,除非RUN_IF的值变为假值,否则作业将被中止。

 $ 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脚本。

每周一运行一个任务:

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

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

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

你也可以在12月24日每年都找一份工作:

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

如果你不想或不能用Rake做这个,另一个选择是用bash从Ruby做到这一点:

 #!/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)。