バージョン0.13以下の Plack::Middleware::Session の Plack::Session::Store::DBI は fork を伴うサーバで利用するとデータベースとの接続でエラーになるなどの問題がありました。バージョン 0.14 でエラーを回避できるオプションが加わっています。
http://search.cpan.org/~miyagawa/Plack-Middleware-Session-0.14/ SYNOPSISにある
builder {
enable 'Session',
store => Plack::Session::Store::DBI->new(
dbh => DBI->connect( @connect_args )
);
$app;
};
このコードでは、builder実行時に DBI->connect も実行されデータベースに接続します。Plack::Loader::Delayedを用いずに、Starman(—preload-app指定)やStarletといったサーバを使用した場合、このデータベース接続後に fork により子プロセスが作成されるので、socket を子プロセス間でシェアしてしまい、エラーとなる危険性がありました。
/* Starmanはデフォルト Plack::Loader::Delayed を使用する件を miyagawa さんより指摘されたので追記 */
そこで、必要になったとき(子プロセスが初回のアクセスを処理する際)に、データベースとの接続を行うようcallbackを指定するオプションが 0.14 で追加されています。
builder {
enable 'Session',
store => Plack::Session::Store::DBI->new(
get_dbh => sub { DBI->connect( @connect_args ) }
);
$app;
};
こっちを使うことで、問題が解決できると思われます。
DBとの永続接続を実現したい場合は、connect_cachedを使うのがよさげです
builder {
enable 'Session',
store => Plack::Session::Store::DBI->new(
get_dbh => sub { DBI->connect_cached( @connect_args ) }
);
$app;
};
また、Scope::Container::DBI を使うと1リクエスト中での永続接続ができます。
builder {
enable 'Scope::Container';
enable 'Session',
store => Plack::Session::Store::DBI->new(
get_dbh => sub { Scope::Container::DBI->connect( @connect_args ) }
);
$app;
};
お試しくださいませ