How can I schedule a 'weekly' job on Heroku?
我在Heroku上部署了一个带有Heroku调度器插件的Rails应用程序,成功地为日常工作工作工作。
现在我想要一份每周的工作,但是调度器插件不允许我选择每周工作。
关于如何实现这一目标的任何建议:
- 我以前尝试过使用rufus调度程序,但它给我带来了一些问题,所以这不是一个选项。详情请参阅此处。
- 我在考虑在日常工作中检查当天的情况。是否有人尝试过,并且对该方法有反馈或知道问题?
- 其他想法很受欢迎。
一种方法是你的第二个要点:
激活heroku cron加载项,并在
激活heroku调度程序加载项,并在
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)。