Hatena::Groupangelos

あんじえろおおおおす!

2009-02-14

複数アプリmod_perl 1プロセスに入れる対応 04:20  複数アプリを mod_perl 1プロセスに入れる対応 - あんじえろおおおおす! を含むブックマーク はてなブックマーク -  複数アプリを mod_perl 1プロセスに入れる対応 - あんじえろおおおおす!

mod_perl で1プロセスに複数アプリを突っ込むと Config や Logger のインスタンスなど、Singleton 化していたものが混同するという問題があったのですが、mod_perl ブランチを経て修正され、先ほどマージされました。id:dann++

解決のきっかけになったのは Sledge::Registrar::contextSledge::Pages::Base でセットするところだそうです。

Angelos#setup の該当部分

    no warnings 'redefine';
    local *Angelos::Registrar::context = sub {$self};

Angelos::Config などは、Angelos 側で Class::Singleton を使用して実装されていたので上記の方法で解決できてるのですが、Logger は Log::Dispatch 自身が Singleton 的な実装になっているためどう回避したのか気になってソースを読んでみました。

Angelos::Logger::Dispatch の build_logger で AppName::Logger::Backend な名前を作って _generate_logger_class に渡して、動的にクラスを生成しています。

sub _generate_logger_class {
    my ($self, $logger) = @_;

    # Log::Dispatch::Config is Singleton class,
    # This causes trobule under mod_perl enviroment,
    # So, we generate application specific logger class
    eval <<"";
        package $logger;
        use base qw/Log\::Dispatch\::Config/;

}

そして、$logger->require して instance 生成してます。

sub build_logger {
    my $self = shift;

    my $logger = join '::', ( $self->_app_class, 'Logger', 'Backend' );
    $self->_generate_logger_class($logger);
    $logger->require;
    $logger->configure_and_watch(
        Log::Dispatch::Configurator::YAML->new( $self->_logger_conf_file ) );
    $logger->instance;
}

ソース読んでて色々発見があって面白いですね!

トラックバック - http://angelos.g.hatena.ne.jp/vkgtaro/20090214