【问题标题】:whenever gem and scheduling a job every n min starting at an offset每当 gem 并从偏移量开始每隔 n 分钟安排一次作业时
【发布时间】:2011-06-10 19:33:36
【问题描述】:

出于惊人的目的,我试图将作业安排为每 5 分钟运行一次的 2 分钟偏移量。也就是说,我希望 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' 示例看起来都在期待字符串格式的时间。上述是否有效或只是碰巧起作用,并且每个选项都不真正支持开始时间。

【问题讨论】:

    标签: ruby gem whenever


    【解决方案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' && echo 'two'"
    end
    

    【讨论】:

    • 谢谢潘。是的,我看到了原始的 cron 语法支持,但想避免写出整个字符串并随时使用以简化我的工作。也没有对任务的依赖,并且有超过 2 个。我只是想错开它们,这样它们就不会每小时都在同一时间运行。
    • @HeretoLearn 不支持纯 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
    

    【讨论】:

    • 这看起来比公认的答案更明智的解决问题的方法。
    • 这对我来说并不像我想象的那样直观。 every 15.minutes + 2.minutes do 变成了这个:17,34,51 * * * * 我想要的是这个:2,17,32,47 * * * * 在 Rails 4.2.5 中使用 When 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)
    

    【讨论】:

    • 此代码显示“at”选项仅使用 1 小时到 1 天,因此很遗憾这不起作用。每当源代码出现间隔 > 1 小时使用时,我都会查看另一个,但在 1 小时以下没有。
    猜你喜欢
    • 2023-03-09
    • 1970-01-01
    • 2011-12-22
    • 2013-07-08
    • 1970-01-01
    • 2021-08-22
    • 2017-12-16
    • 1970-01-01
    • 2018-07-22
    相关资源
    最近更新 更多