Circus+WEBrick+Rackを動かしてみる

前回の続き。
自作したサーバープログラムをCircusで動かす - 偏った言語信者の垂れ流し
さすがにもうちょっとまともなサーバーをRubyで動かしてみたかったので、WEBrickでRackアプリケーションを動かしてみることにした。

Rackのインストール

環境がUbuntu12.04、Ruby1.9.1なのでとりあえずaptで入れてしまう。

$ sudo aptitude install ruby-rack

hello_rack.rb

WEBrickのHTTPServerクラスを継承して、Circusから渡されるfdを使えるようにした。
RackアプリケーションはHello, world!と表示するだけのシンプルなもの。

require 'socket'
require 'webrick'
require 'webrick/utils'
require 'rubygems'
require 'rack'

# WEBrickのサーバーをファイルディスクリプタからのSocketに対応させたもの
class FDHTTPServer < WEBrick::HTTPServer
  def initialize(config={})
    config[:DoNotListen] = true
    super(config)
    listen(config[:FD])
  end

  def listen(fd)
    sock = TCPServer.for_fd(fd)
    WEBrick::Utils::set_close_on_exec(sock)
    @listeners += [sock]
  end
end

# Rackアプリケーション
class MyApp
  def call(env)
    [200, {"Content-Type" => "text/plain"}, ["Hello, world!\n"]]
  end
end

server = FDHTTPServer.new({
  :FD => ARGV[0].to_i
})
server.mount "/", Rack::Handler::WEBrick, MyApp.new

['INT', 'TERM'].each {|signal|
  Signal.trap(signal){ server.shutdown }
}

server.start

hello_rack.ini

Circusの設定ファイル。前回と特に変わらず。

[circus]
check_delay = 5
endpoint = tcp://127.0.0.1:5555

[watcher:hello]
cmd = ruby hello_rack.rb $(circus.sockets.web)
use_sockets = True
numprocesses = 5

[socket:web]
host = 0.0.0.0
port = 8000

実行

$ circusd hello_rack.ini
2012-07-20 06:51:24 [13119] [INFO] Starting master on pid 13119
2012-07-20 06:51:24 [13119] [INFO] sockets started
2012-07-20 06:51:24 [13119] [INFO] hello started
2012-07-20 06:51:25 [13119] [INFO] Arbiter now waiting for commands

curlで動作を確認。

$ curl http://127.0.0.1:8000/
Hello, world!

がんばればUnicornの代わりにCircusを使えるかもしれませんね。