バージョン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;
};

お試しくださいませ

このブログ記事について

このページは、Masahiro Naganoが2011年3月30日 14:43に書いたブログ記事です。

ひとつ前のブログ記事は「Nagios 統合監視 [実践] リファレンス を献本頂きました」です。

次のブログ記事は「Scope::Container::DBI で Amon2::DBI を使う」です。

最近のコンテンツはインデックスページで見られます。過去に書かれたものはアーカイブのページで見られます。

ウェブページ

OpenID対応しています OpenIDについて
Powered by Movable Type 4.27-ja