Railsを使っていると「日時バッチ」「1時間に一度の処理」など定期的に実行したいタスクが出てきます。
管理方法としては普通にcrontabに書き込んだりJenkinsなどを使ってそれらのタスクを管理する方法があります。
しかし可能ならRailsプロジェクト上で実行時間なども管理したいです。
そういった時に使えるGemがwheneverです。
これを使うと下のようにRubyでcrontabの管理ができます。
every :day, at: '12:20' do runner 'MyModel.execute' end every :sunday, at: '12:30' runner 'MyModel2.execute' end
wheneverを使う準備
インストールはBundlerを使います。
gem 'whenever'
インストールが終わったらwheneverizeコマンドでwheneverの初期化をします。
wheneverize
実行するとconfig/schedule.rbというファイルが作られます。
ファイルの内容は下の通りです。
# Use this file to easily define all of your cron jobs. # # It's helpful, but not entirely necessary to understand cron before proceeding. # http://en.wikipedia.org/wiki/Cron # Example: # # set :output, "/path/to/my/cron_log.log" # # every 2.hours do # command "/usr/bin/some_great_command" # runner "MyModel.some_method" # rake "some:great:rake:task" # end # # every 4.days do # runner "AnotherModel.prune_old_records" # end # Learn more: http://github.com/javan/whenever
wheneverの使い方
まずは先程作られたconfig/schedule.rbに定期実行したいタスクを書きます。
下は4日おきにMyModelのcreate!を呼び出すタスクです。
every 4.days do runner "MyModel.create!" end
タスクを書いたらcrontabにどんな形で書き込まれるか確認をします。
確認にはwheneverコマンドを使います。
whenever
wheneverコマンドを実行すると下のようにどのようにcrontabに書き込まれるかが表示されます。
crontabへの反映もwheneverコマンドを使います。
下のように--update-crontabを付けて実行します。
whenever --update-crontab
実行後crontab -lで確認するとしっかり書き込みができている事が分かります。
wheneverのフォーマット
wheneverではデフォルトでcommand, rake, runner, scriptというメソッドが用意されています。
実行結果はそれぞれ下の通りです。
every 4.days do command "bundle install" # → /bin/bash -l -c 'bundle install' rake "my_task" # → /bin/bash -l -c 'cd /Users/xxxx/Desktop/my_app && RAILS_ENV=production bundle exec rake my_task --silent' runner "MyModel.create!" # → /bin/bash -l -c 'cd /Users/xxxx/Desktop/my_app && bundle exec bin/rails runner -e production '\''MyModel.create!'\''' script "my_script" # → /bin/bash -l -c 'cd /Users/xxxx/Desktop/my_app && RAILS_ENV=production bundle exec script/my_script' end
自分で上記以外のメソッドを追加する事もできます。
job_type :my_job, "cd :path && :bundle_command rake :task" every 4.days do my_job "my_task" # → /bin/bash -l -c 'cd /Users/xxxx/Desktop/my_app && bundle exec rake my_task' end
実行時間の書き方も色々な種類があります。
下のように文字列でcrontabと同じ形式に書く事ができます。
非常に分かりやすい書き方です。
every '0 0,1,2 * * *' do # → 0 0,1,2 * * * runner 'MyModel.execute' end
毎日決まった時間に実行する場合は下のような書き方も分かりやすいです。
every :day, at: '12:20' do # → 20 12 * * * runner 'MyModel.execute' end
特定の曜日だけ実行する事もできます。
every :sunday, at: '12:30' do # → 30 12 * * 0 runner 'MyModel.execute' end