WheneverでRailsのバッチ処理

WheneverはCronを利用して繰り返し処理を行うためのライブラリ。
シェルコマンドやRailsのRunner、RakeタスクなどのジョブをCronで実行できる。
実際のところCrontabへの登録を補助してくれるだけなのだが、そのシンプルさがかえって分かりやすい。

バッチ処理の管理にうってつけ。
タイトルではRailsとなっているがRails以外でも利用できる。

以下はRails3での使い方メモ。

導入

Gemfileに以下の行を追加してbundle install

gem 'whenever', :require => false

schedule.rbの編集

config/schedule.rbにスケジュール設定を書いていく。

bundle exec wheneverize .

を実行するとひな形を作ってくれるので、それを元に編集していくのが吉。
スケジュールは「every」に続いて英語で読み下せる形でも書けるし、crontabの形式でも書くことができる。

set :output, {:error => 'log/error.log', :standard => 'log/cron.log'}

every 3.hours do
  runner "CacheUtil.clear_all"
end

every :monday, :at => '4:30 am' do
  runner "Item.refresh"
end

every '0 0 * * *' do
  runner "Item.refresh"
end

setで変数を定義することで挙動を変えることができる。
例えばoutputでログの場所を指定したり、environmentで環境を指定するなど。

現在のパスを取得するのにRails.rootは使えないが代わりにWhenever.pathが使える。

スケジュールの適用

登録内容の確認
bundle exec whenever

を実行するとcrontabの内容をコンソール出力。
この時点ではまだcrontabに登録されてはいない。

Crontabへ登録
bundle exec whenever --update-crontab

–update-crontabオプションをつけるとcrontabに登録する。
Whenever以外で登録されていたジョブが上書きされることはない。

Crontabから削除
bundle exec whenever --clear-crontab

Cronを止めたい場合は–clear-crontabですべて削除。
登録の場合と同様にWhenever管理外のジョブが削除されることはない。

ジョブタイプの定義

基本はcommandでなんでもできると思うけど、同じようなコマンドを何個も登録するようならジョブタイプを定義すればDRYにできる。

詳細は本家のREADME参照。
以下のサンプルコードのように簡単に作れる。

job_type :awesome, '/usr/local/bin/awesome :task :fun_level'

every 2.hours do
  awesome "party", :fun_level => "extreme"
end

RVMとの組み合わせで使う場合

.rvmrcに以下の行を追加

rvm_trust_rvmrcs_flag=1

手元のMacだとRVMを使ってくれなかったけど原因はわからない。
Linux上のProduction環境では問題なかったので不問とする。

Capistranoとの組み合わせで使う場合

Whenever側で仕組みが用意されているのでそれに沿って行う。
ちょっと長くなるのでまたの機会に。すぐ見たい人は本家のREADME参照。

2011/06/19追記

CapistranoでWhenever

参考