beanstalkを使ってみる
※Amazon Elastic Beanstalkは関係ありません
http://kr.github.com/beanstalkd がちょっと気になったので使ってみた
インストール
sudo apt-get install beanstalkd
でインストール出来る。 もちディストリビューションによって違うと思うので、そこら辺はドキュメント参照するかapt-getなりyumなりで検索して探してインストールする
んでその後起動しておく。デフォルト推奨ポート番号は11300な模様
Rubyのライブラリをインストール
gem install beanstalk-client
まぁ色々クライアントライブラリはあるみたいですが、とりあえずbeanstalk-clientってのを使う
worker.rb
require "beanstalk-client"
beanstalk = Beanstalk::Pool.new(["127.0.0.1:11300"])
beanstalk.watch("sample")
loop do
job = beanstalk.reserve
stat = job.stats
p stat["tube"]
p job[:name]
job.delete
end
watchでキュー名(beanstalk的にはtubeというべきなのかも)を指定出来る。デフォルトは"default"な模様。でworker側でクライアント側から来たキュー名を特定するにはstatsで参照可能な模様
んでソース上で
class Beanstalk::Job
def [](name)
ybody[name]
end
def []=(name, val)
ybody[name] = val
end
# 以下省略
end
っていうふうになってるので普通にjob[name]で参照可能。だけどこれyputされた際に限るものだと思われるので、普通の文字列なようなのがputでぶっこんで来られた場合にはjob.bodyで取得できる
client.rb
require "beanstalk-client"
beanstalk = Beanstalk::Pool.new(["127.0.0.1:11300"])
beanstalk.use("sample")
beanstalk.yput({ :name => "hoge" })
まぁ上でも書いたようにyputを使えばHashとかでも流せる。一応シリアライザー的なのはYAMLな模様。まぁだから接頭辞にyが付いてるんだと思うけど
追記
beanstalkのEM(EventMachine)なライブラリもある模様で
worker.rbが
require "em-beanstalk"
EM.run do
beanstalk = EM::Beanstalk.new
beanstalk.watch("sample") do |tube|
puts "watched tube: #{tube}"
end
beanstalk.each_job do |job|
p job.body
beanstalk.delete(job) {
id = job.id
puts "delete job: #{id}"
}.on_error do |msg|
p msg
end
end
end
な感じで、client.rbが
require "em-beanstalk"
EM.run do
beanstalk = EM::Beanstalk.new
beanstalk.put("hoge") do |id|
p id
EM.stop
end
end
な感じ。だがクライアントまでEventMachineにする必要あるのかは分からないけど。又、putの引数にオブジェクトとか指定するとワーカー側で取る際にはinspectされてる模様。それをevalするのもどうかと思うのでJSONなりYAMLなりでダンプして流した方が良いのではと思う所
ちなみにWorkerがEMでClientがbeanstalk-clientでも問題無いみたい。ただシリアライズ的な所は未確認