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

T C*_*T C 21 ruby-on-rails heroku scheduled-tasks

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

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

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

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

Pie*_*rre 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
Run Code Online (Sandbox Code Playgroud)

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

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

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

  • 不推荐使用cron附加组件,并且将停止使用cron加载项以支持调度程序.也就是说,你建议的方法是合理的,但可以通过activesupport更好地表达:Time.now.friday? (3认同)

小智 10

仅使用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 
Run Code Online (Sandbox Code Playgroud)

我已经使用此代码模仿当地时区的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 Code Online (Sandbox Code Playgroud)


小智 8

它的效果并不理想,但我已经采取了增加一个RUN_IF环境变量来耙任务通过Heroku的运行:调度器让我每周和每月的时间表工作.

# 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 Code Online (Sandbox Code Playgroud)

如果在没有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)
Run Code Online (Sandbox Code Playgroud)

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