xengineer’s diary

結果、メモ的な内容になっています。

whenever gemでどう書くの?

はいねもとです。

cron管理に、whenever gemを使っています。

github.com

今回、下記設定をしようとして、謎挙動をしたので、とりあえずメモ。

  • 2:00 - 23:30までは、30min毎に、task Aを実行する

まずは、バージョン。

  • whenever (0.9.4)
  • chronic (0.10.2)

Wheneverは導入が超簡単なcrontab管理ライブラリGemです![Rails4.2 x Ruby2.3] - 酒と泪とRubyとRailsと

上記記事を参考にして、schedule.rbにはこんな感じで記載してみました。

regular_sync_schedule = (2..23).map {|_| ["#{_}:00", "#{_}:30"] }.flatten
  every 1.day, at: regular_sync_schedule do
    runecho "bb"
end

そして、実行!えいやー。

$ RAILS_ENV=development bundle exec whenever --update-crontab

cronの設定を確認。

$ crontab -l
# Begin Whenever generated tasks for: /Users/nemoto_hideaki/work/PROJECT/testp/config/schedule.rb
0,30,0,30 14,15,16,17 * * * /bin/bash -l -c 'echo test1 '\''bb'\'' >> log/cron_log.log 2>&1'

0,30 6,7,8,9,10,11,12,13,18,19,20,21,22,23 * * * /bin/bash -l -c 'echo test1 '\''bb'\'' >> log/cron_log.log 2>&1'

# End Whenever generated tasks for: /Users/nemoto_hideaki/work/PROJECT/testp/config/schedule.rb

ぬぬー???なんかおかしい・・・

みやすく揃えてみると・・・

[min]
0,30,0,30
0,30

[hour]
14,15,16,17
6,7,8,9,10,11,12,13,18,19,20,21,22,23

[others]
* * * /bin/bash -l -c 'echo test1 '\''bb'\'' >> log/cron_log.log 2>&1'
* * * /bin/bash -l -c 'echo test1 '\''bb'\'' >> log/cron_log.log 2>&1'

やっぱり色々おかしい・・・

仕方ないので、原因を追ってみる。

Wheneverを呼び出すと、わーーーー、っと流れに流れて、

Whenever::Output::Cron#initialize が呼ばれます。

その中で、先程記載した下記設定の、"at" の部分が解釈されるみたい。

regular_sync_schedule = (2..23).map {|_| ["#{_}:00", "#{_}:30"] }.flatten
  every 1.day, at: regular_sync_schedule do
    runecho "bb"
end

実際のコードは下記。

def initialize(time = nil, task = nil, at = nil)
  @at_given = at
  @time = time
  @task = task
  @at   = at.is_a?(String) ? (Chronic.parse(at) || 0) : (at || 0)
end

んで、ここのどこでおかしくなってるかというと・・・

Chronic.parse(at)

これですこれ。

なんか、この人に、1:00 - 5:00のStringを渡すと、なぜか、PMに変換されちゃう。

$ irb
irb(main):001:0> require 'chronic'
=> true
irb(main):002:0> Chronic.parse("5:00")
=> 2016-09-24 17:00:00 +0900
irb(main):003:0> Chronic.parse("6:00")
=> 2016-09-24 06:00:00 +0900
irb(main):004:0> Chronic.parse("5:00 am")
=> 2016-09-24 05:00:00 +0900

ほら。最後に、amをくっつけたやつは大丈夫。

Chronic gemまで見てみる気力がなかったので、一旦下記の設定をして逃げるある。

regular_sync_schedule_am = (2..11).map {|_| ["#{_}:00 am", "#{_}:30 am"] }.flatten
regular_sync_schedule_pm = (12..23).map {|_| ["#{_}:00 pm", "#{_}:30 pm"] }.flatten

every 1.day, at: regular_sync_schedule_am do
  runecho1 "aa"
end

every 1.day, at: regular_sync_schedule_pm do
  runecho1 "aa"
end

23:00とかにもpmってついちゃうけど、それは問題なく動くので気にしない。

最終こうなったよ。

0,30 2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23 * * * /bin/bash -l -c 'echo test1 '\''aa'\'' >> log/cron_log.log 2>&1'

ちゃんちゃん。