我在Heroku上部署了一个Rails应用程序,Heroku调度程序附加组件成功地用于日常工作。
现在我想要一个每周工作,但是调度程序加载项不允许我每周选项。
关于如何实现这一目标的任何建议:
答案 0 :(得分:36)
一种方法是你的第二个要点之一:
激活Heroku cron加载项,并在 cron.rake
app/lib/tasks
任务
激活Heroku调度程序加载项,并在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的反馈调整我的答案。
答案 1 :(得分:10)
仅使用shell代码的备用选项。每小时设置Heroku调度程序,并与日期命令进行比较:
# 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
答案 2 :(得分:8)
这并不理想,但我已经开始添加一个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)
与上述其他想法类似,但我更喜欢将调度细节移出应用程序代码。
答案 3 :(得分:1)
正如所讨论的over here,并使用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
答案 4 :(得分:0)
如果你不想或不能用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)。