先日の記事でもちょろっと紹介しましたが、RSSリーダーを開発した際にフィード更新ジョブを定期的に発行するためにclockworkというgemを使用しました。
RSSリーダーの記事更新のバックグラウンドジョブ概要 - ぴよログ
単独で使う
まずはRuby単独で使う方法です。ローカルマシンで定期的にスクリプトを動かしたいときなどに使えます(そんなときあるか!?)。
まずgemを導入します。普通にgem install
でいけます。
$ gem install clockwork
次にコンフィグファイル的なものを書きます。例えばclock.rb
というような名前で作るとします。
require 'clockwork'
module Clockwork
def one_minute
p "minutely job"
end
def one_hour
p "hourly job"
end
handler do |job|
self.send(job.to_sym)
end
every(1.minute, 'one_minute')
every(1.hour, 'one_hour')
end
最後の2行で1分ごとのジョブと1時間ごとのジョブを設定しています。そしてhandler
に処理記述します。この例ではジョブ名と同じメソッドを定義しておいて、send
によってそちらを呼ぶようにしています。
フォアグラウンド実行
フォアグラウンド実行を行うときは次のように実行します。
$ clockwork clock.rb
I, [2014-02-16T11:11:17.128897 #97926] INFO -- : Starting clock for 2 events: [ one_minute one_hour ]
I, [2014-02-16T11:11:17.129034 #97926] INFO -- : Triggering 'one_minute'
"minutely job"
I, [2014-02-16T11:11:17.129107 #97926] INFO -- : Triggering 'one_hour'
"hourly job"
I, [2014-02-16T11:12:17.182378 #97926] INFO -- : Triggering 'one_minute'
"minutely job"
I, [2014-02-16T11:13:17.231925 #97926] INFO -- : Triggering 'one_minute'
"minutely job"
実行すると同時に1時間毎のジョブと1分ごとのジョブが実行され、それ以降は指定した間隔でジョブが動いていきます。
at
オプションを使うことでcronのように◯時XX分に実行する、というような指定も可能です。
every(1.hour, 'hourly', :at => '**:30')
バックグラウンド実行(デーモン)
定期実行という機能の特性を考えるとバックグラウンドで実行したいケースがほとんどだと思います。そのためにはclockwork
と一緒についてくるclockworkd
を使います。
$ clockworkd -c clock.rb start --log
-c
はコンフィグファイルを指定というようなニュアンスだと思われます。clock.rb
ファイルを指定してstart
すればバックグラウンドで起動します。--log
オプションを付けることにより、フォアグラウンド実行のとき標準出力されていたログがファイルに出るようになります。
Railsと使う
アプリケーションと一緒に使うことでより実用的になります。Railsの場合はclockwork
をrequireしたあとでRailsの環境をrequireすることでRailsのコードを使えるようになります。
Railsの環境を読み込むにはconfig/boot
とconfig/environment
をrequireします。requireする際のパスに注意して書く必要があるのですが、clockworkのコンフィグファイルがboot
などと同じくconfig
にある場合は、
require File.expand_path('../boot', __FILE__)
require File.expand_path('../environment', __FILE__)
などと書きます。
これをやっておくことでRailsのモデルなどにアクセスできるようになって、より実用的な使い方をできるようになりますね。
require 'clockwork'
require File.expand_path('../boot', __FILE__)
require File.expand_path('../environment', __FILE__)
module Clockwork
handler do |job|
p "#{job}: user count => #{User.count}"
end
every(1.minute, 'minute')
end