beanstalkを使ってみる

2012-09-13T00:00:00+00:00 Ruby

※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でも問題無いみたい。ただシリアライズ的な所は未確認

jqplot foremanを使ってみる