Resque の README を参考にメモ。
class Archive
@queue = :file_serve
def self.perform(repo_id, branch = 'master')
repo = Repository.find(repo_id)
repo.create_archive(branch)
end
end
class Repository
def async_create_archive(branch)
Resque.enqueue(Archive, self.id, branch)
end
end
klass, args = Resque.reserve(:file_serve) klass.perform(*args) if klass.respond_to? :perform
$ cd app_root $ QUEUE=file_serve rake resque:work
GitHub では、以下の様なジョブを Resque で処理している。
ジョブは JSON オブジェクトとしてキューに置かれる。
{
'class': 'Archive',
'args': [ 44, 'masterbrew' ]
}
パラメータは JSON エンコード可能なものに限られる。
examples/ ディレクトリにあるサンプル参照との事。
Resque のワーカーは動き続ける rake タスク。
start
loop do
if job = reserve
job.process
else
sleep 5
end
end
shutdown
ワーカーの起動は以下のようにすれば良い。
$ QUEUE=file_serve rake resque:work
デフォルトでは Resque はアプリケーションの environment を知らない。 Resque を Rails プラグインとしてインストール済みなら以下のように environment を指定できる。
[RAILS_ROOT/] $ QUEUE=file_serve rake environment resque:work
これによって、ワーカーを起動する前に environment をロードする。 この代わりに、resque:setup タスクを定義する事で、依存タスクに environment を指定できる。
task "resque:setup" => :environment
Resque は標準では標準出力へのログ出力をサポートしている。VERBOSE 環境変数によってデバッグ情報を吐き出す事もできる。
$ VVERBOSE=1 QUEUE=file_serve rake environment resque:work
Resque は数値優先度をサポートしていないが、代わりに "queue list" と呼ばれる任意のキュー順序を利用する事ができる。
$ QUEUES=file_serve,warm_cache rake resque:work
ワーカーをこの様に起動した場合、ワーカーはまず file_serve キューをチェックし、キューにジョブがなくなったら warm_cache キューをチェックする様になる。
起動時に存在しないキューも含めて、全てのキューのジョブを実行するワーカーを起動するためには、以下の様にすればよい。
$ QUEUE=* rake resque:work
この場合、キューリストの順序はアルファベット順になる。
Resque は無秩序を当然のものと考える。
$ ps -e -o pid,command | grep [r]esque 92099 resque: Forked 92102 at 1253142769 92102 resque: Processing file_serve since 1253142769
$ ps -e -o pid,command | grep [r]esque 92099 resque: Waiting for file_serve,warm_cache
Resque のワーカーはいくつかのシグナルを受け付ける。
Resque は、Sinatra ベースのフロントエンドを持っている。
$ resque-web
rackup ベースなので、調整可能。
$ resque-web -p 8282
設定ファイルのパスを指定する事もできる。
$ resque-web -p 8282 rails_root/config/initializers/resque.rb
config.ru によって Passenger を利用する事ができる。
Rack::URLMap(Rack のミドルウェア)を使えば、URL の調整も可能。
require 'resque/server' run Rack::URLMap.new \ "/" => Your::App.new, "/resque" => Resque::Server.new
どちらを選ぶべきかの考察。
Rails で開発しているなら、データベースと ActiveRecord は利用可能であるはずなので、DelayedJob は非常に簡単にセットアップでき、よく働いてくれる。 GitHub では、しばらくの間利用していて、おそらく 200,000,000 個のジョブを処理してきた。
常に Resque がより良い選択という訳ではないので、用途に応じて選択する必要がある。
$ brew install redis $ redis-server /usr/local/etc/redis.conf
$ git clone git://github.com/defunkt/resque.git $ cd resque $ rake redis:install dtach:install $ rake redis:start
Resque の rake タスクでインストールと起動を行える。
横道にそれるが、気になるので Homebrew についても調査した。
要するに、パッケージ管理用ソフトウェア。
$ gem install redis redis-namespace yajl-ruby --source=http://gemcutter.org
yajl-ruby がインストールできなければ、json をインストールする事で、Resque は代わりにそれを使う様になる。
まず、gem をインストールする。
$ gem install resque --source=http://gemcutter.org
アプリケーションから Resque を使える様にする。
require 'resque'
アプリケーションを起動する。
$ rackup config.ru
これで、Resque のジョブをアプリケーションから作成可能になった。
rake タスクは、Rakefile に以下を加えれば良い。
require 'your/app' require 'resque/tasks'
Rack の場合と同様に、Resque の gem をインストールする。
アプリケーションから Resque を使える様に、initializer を追加する。
$ cat config/initializers/load_resque.rb require 'resque'
アプリケーションを起動する。
$ ./script/server
rake タスクは、Rakefile に以下を加えれば良い。
require 'resque/tasks'
忘れずに、resque:setup タスクを定義し、environment タスクを呼び出せる様にしておく事。
development: localhost:6379 test: localhost:6379 staging: redis1.se.github.com:6379 fi: localhost:6379 production: redis1.ae.github.com:6379
rails_root = ENV['RAILS_ROOT'] || File.dirname(__FILE__) + '/../..' rails_env = ENV['RAILS_ENV'] || 'development' resque_config = YAML.load_file(rails_root + '/config/resque.yml') Resque.redis = resque_config[rails_env]
$ git clone git://github.com/defunkt/resque.git $ cd resque/examples/demo $ rackup config.ru $ open http://localhost:9292/
$ VERBOSE=true QUEUE=default rake resque:work
上記を実行すると、以下の様な出力を得られるはず。
*** Starting worker hostname:90185:default
*** got: (Job{default} | Demo::Job | [{}])
Processed a job!
*** done: (Job{default} | Demo::Job | [{}])
VVERBOSE でより多くの情報を出力させる事ができる。
$ VVERBOSE=true QUEUE=default rake resque:work
*** Starting worker hostname:90399:default
** [05:55:09 2009-09-16] 90399: Registered signals
** [05:55:09 2009-09-16] 90399: Checking default
** [05:55:09 2009-09-16] 90399: Found job on default
** [05:55:09 2009-09-16] 90399: got: (Job{default} | Demo::Job | [{}])
** [05:55:09 2009-09-16] 90399: resque: Forked 90401 at 1253141709
** [05:55:09 2009-09-16] 90401: resque: Processing default since 1253141709
Processed a job!
** [05:55:10 2009-09-16] 90401: done: (Job{default} | Demo::Job | [{}])
$ open http://localhost:9292/resque/
Keyword(s):[ruby] [backgroundjob]
References: