#ruby #gem #whenever
#ruby #rubygems #всякий раз, когда
Вопрос:
Для ошеломляющих целей я пытаюсь запланировать задания со смещением на 2 минуты, которые выполняются каждые 5 минут. То есть я хочу, чтобы 1 задание выполнялось с частотой 1,6,11,16 .. а другое — с частотой 2,7,12,17…
Я не смог найти пример для этого. Итак, я попытался:
every 5.minutes, :at=> 1 do
command "echo 'you can use raw cron sytax too'"
end
Кажется, это работает, но все примеры ‘:at’, похоже, ожидают время в строковом формате. Допустимо ли вышеуказанное или просто работает, и каждый параметр на самом деле не поддерживает время запуска.
Ответ №1:
Похоже, у вас есть зависимость между двумя заданиями, поэтому, я думаю, есть два способа справиться с этим. Если вы хотите работать с 1,6,11,16 и так далее, как следует из вашего вопроса, Тогда просто используйте необработанный синтаксис cron:
every '0,5,10,15,20,25,30,35,40,45,50,55 * * * *' do
command "echo 'you can use raw cron syntax one'"
end
every '1,6,11,16,21,26,31,36,41,46,51,56 * * * *' do
command "echo 'you can use raw cron syntax two'"
end
Но, вероятно, лучше выполнить второе задание после завершения первого. Это должно гарантировать, что задания не перекрываются и что второе выполняется только после завершения первого.
every 5.minutes do
command "echo 'one' amp;amp; echo 'two'"
end
Комментарии:
1. Спасибо Pan. Да, я видел поддержку синтаксиса raw cron, но хотел избежать записи всей строки и использовать whenever, чтобы упростить мою работу. Также нет зависимости от задач, и их более 2. Я просто хочу расположить их в шахматном порядке, чтобы все они не запускались в одно и то же время каждый час.
2. @HeretoLearn whenever не поддерживает такой синтаксис в чистом ruby, поэтому вам придется использовать необработанный синтаксис crontab. Если задания не зависят друг от друга, я бы рекомендовал запускать их, используя первый пример.
Ответ №2:
every
ожидает целое число.
Чтобы избежать проблемы с громоподобным стадом, вы можете сделать это.
every 5.minutes - 10.seconds do
command "echo first task"
end
every 5.minutes 10.seconds do
command "echo second task"
end
Вы также можете рандомизировать смещение
def some_seconds
(-10..10).to_a.sample.seconds
end
every 5.minutes some_seconds do
command "echo first task"
end
every 5.minutes some_seconds do
command "echo second task"
end
Как и другие ответы, это не будет работать для задач, зависящих друг от друга. Если ваши задачи зависят друг от друга, вам следует использовать rake
для обработки этого за вас или запустить следующую вручную в вашей задаче.
# shedule.rb
every 5.minutes do
rake 'jobs:last_one'
end
# Rakefile.rb
namespace :jobs do
task :first_one do
sh 'first command'
end
task second_one: [:first_one] do
sh 'second_command that_should_run_after_first_one'
end
task last_one: [:second_one] do
sh 'last_command that_should_run_after_all_commands'
end
end
Комментарии:
1. Это выглядит более разумным способом решения проблемы, чем общепринятый ответ.
2. У меня это сработало не так интуитивно, как я предполагал.
every 15.minutes 2.minutes do
Получилось вот что:17,34,51 * * * *
то, к чему я стремился, было таково:2,17,32,47 * * * *
Работа в Rails 4.2.5 с Whenever gem 0.9.4
Ответ №3:
Да, это должно быть допустимо. Посмотрите на https://github.com/javan/whenever/blob/master/lib/whenever/cron.rb
Посмотрите на метод parse_time . Эти строки, в частности:
when 1.hour...1.day
hour_frequency = (@time / 60 / 60).round
timing[0] = @at.is_a?(Time) ? @at.min : @at
timing[1] = comma_separated_timing(hour_frequency, 23)
Комментарии:
1. Этот код показывает, что опция ‘at’ используется только от 1 часа до 1 дня, так что это, к сожалению, не сработает. Я просмотрел другой исходный код everywhere, и оказалось, что интервал > 1 часа используется at, но менее 1 часа — нет.