External Process

CouchDB で外部プロセスをHTTPリクエストから起動する方法。Wikipythonの例があるので、rubyで。

基本的には update notification と同じ。

#!/usr/bin/env ruby
require 'rubygems'
require 'json'
require 'logger'

run = true
logger = Logger.new("/tmp/external.log")
logger.info "Start CouchDB process"
while run do
   input = gets
   if input == nil
      run = false
   else
      req = JSON(input)
      logger.info req.inspect
      # ここにレスポンスハンドラーを書く

      # 戻りは JSON 形式で、"標準出力"に書き出す
      res = { :code => 200, 
              :json => { :data => "Hello" }, 
              :headers => { "Content-Type" => "text/plain" }}
      puts res.to_json

      # 最後に \n を出力
      puts ""

      # flush してあげないと、CouchDB側がProcess Timeoutを検出してしまう
      $stdout.flush
   end
end 
logger.info "End CouchDB process"

設定がわかりにくいんだけれど、/usr/local/etc/couchdb/default.ini に書く。

[external]
rb = /usr/local/share/couchdb/server/external.rb

[httpd_db_handlers]
_design = {couch_httpd_db, handle_design_req}
_temp_view = {couch_httpd_view, handle_temp_view_req}

; これを追加。/db/_rb というパスに対して、"rb" というキーのExternalプロセスをひもづける
_rb = {couch_httpd_external, handle_external_req, <<"rb">>}

ところで、ぱっと見、stdin から受け取るって、ものすごくシリアライズされて全然パフォーマンスでない気がするんだけど。あとで ab で試してみる。