Подтвердить что ты не робот

Как я могу запланировать еженедельную работу на Heroku?

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

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

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

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

Ответ 1

Один из подходов - это ваш второй пункт:

активировать дополнение к керону Heroku и добавить задачу 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 рекомендует переключиться на дополнение к планировщику. Однако это не изменяет подход к еженедельной работе.

EDIT2: корректировки моего ответа на основе обратной связи от заката.

Ответ 2

Альтернативный вариант с использованием только кода оболочки. Настройте планировщик 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 

Ответ 3

Это не идеальный вариант, но я добавил добавить переменную среды 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

Если задача rake выполняется без переменной RUN_IF, она будет запущена. В противном случае задание будет прервано, если значение RUN_IF не станет равным значению false.

$ 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)

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

Ответ 4

Как обсуждалось здесь, и используя приведенную выше логику от Rob, вот сценарии 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

Ответ 5

Если вы не хотите или не можете сделать это с помощью 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 "[email protected]"

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