Как я могу запланировать «еженедельную» работу на Heroku? - PullRequest
21 голосов
/ 23 марта 2012

У меня установлено приложение Rails в Heroku с надстройкой планировщика Heroku, успешно работающей для ежедневных заданий.

Теперь я хочу еженедельное задание , но надстройка планировщика делаетне позволяйте мне еженедельный вариант.

Любые предложения о том, как мне это сделать:

  • В прошлом я пытался использовать rufus-scheduler, но это вызывало у меня некоторые проблемы, так что это не вариант.Смотрите здесь для подробностей.
  • Я думаю о чем-то вроде проверки текущего дня в повседневной работе.Кто-нибудь пробовал это и имел обратную связь или знал о проблемах с подходом?
  • Другие идеи высоко ценится.

Ответы [ 5 ]

36 голосов
/ 23 марта 2012

Один из подходов будет подходить для вашей второй точки:

активируйте дополнение 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

У вас даже есть роскошь определять день, когда вы хотите, чтобы ваша задача выполнялась; о) (5 на пятницу)

РЕДАКТИРОВАТЬ: кстати, Cron устарела, и Heroku рекомендует переключиться на их надстройку планировщика. Это не меняет подход к еженедельной работе.

РЕДАКТИРОВАТЬ 2: корректировки моего ответа на основе обратной связи от Sunkencity.

10 голосов
/ 02 сентября 2013

Альтернативный вариант с использованием только шелл-кода. Настройте планировщик 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 
8 голосов
/ 17 апреля 2013

Это не идеально, но я принял решение добавить переменную среды 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_IF, он будет работать.В противном случае задание будет прервано, если значение 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)

Аналогично другим идеям выше, но я предпочитаю удалять детали планирования из кода приложения.

1 голос
/ 04 января 2017

Как обсуждено здесь , и с использованием вышеупомянутой логики от Роба, вот сценарии bash с разбивкой по дням недели, раз в месяц и на определенную дату.

Запуск задания каждый понедельник:

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

Запуск задания каждый 1-й день в месяце:

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

Вы также можете запускать задание каждый год 24 декабря:

if [ "$(date +%m)" = 12 ] && [ "$(date +%d)" = 24 ]; then MY_COMMAND; fi
0 голосов
/ 22 мая 2013

Если вы не хотите или не можете сделать это с Rake, другой вариант - сделать это с Ruby из bash:

#!/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 "$@"

Это работает даже для неруби-проектов (как в моем случае: Clojure).

...