всякий раз, когда gem и планирование задания каждые n минут, начиная со смещения

#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 часа — нет.