CGI::Session::PStore でハング

CGI::Session::PStore を使用した CGI を mod_ruby で動かしていると、極まれにハングしてしまうことがありました。strace と /proc//fd を見てみたところ、同じプロセスが同じセッションデータファイルを二重にロックしようとして止まってしまっているようです。

現象からして GC まわりの問題だろうと思ったのですが、試しにこんなプログラムを作ってみたらあっさりと再現しました。

require 'tmpdir'
require 'cgi/session/pstore'

STDIN.reopen "/dev/null"
Dir.mktmpdir do |dir|
  10000.times do |i|
    p i
    cgi = CGI.new
    session = CGI::Session.new cgi, 'database_manager'=>CGI::Session::PStore, 'session_id'=>'hogehoge', 'tmpdir'=>dir
    session['hoge'] = 'fuga'
    session.update
#    session.close
  end
end

session.close を GC に任せていたせいで、GC のタイミングによってデッドロックになっていたようです。session.close の行を生かすことで発生しなくなりました。

ということで CGI::Session#close 重要。