CGI::Application::Plugin::Cache::Adaptive Release
  先日、奥さんの要望によりCache::AdaptiveをCGI::Applicationで使いやすくするプラグインを書きました。
  現在はversion 0.03でCPANにCGI::Application::Plugin::Cache::Adaptiveとしてアップされています。
Cache::Adaptive自体については、CPANのドキュメントないしは、奥さんの下記の関連エントリをご覧下さい。
使い方や実装方法について簡単に説明してみようと思います。
すぐ分かる使い方
実際はやる事は二つしかありません。
- CGI::Applicationを継承したクラス内でcache_adaptive()メソッドを使ってCache::Adaptiveまたは、派生クラス(例えばCache::Adaptive::ByLoad)のインスタンスを突っ込みます。
- CGI::Applicationを継承したクラス内でCacheさせたいメソッドにcode attributeとして、Cacheableを指定します。
この二つに関して書いて行きます。
cache_adaptive()による準備
sub setup {
    my $self = shift;
    ### snip
    $self->cache_adaptive({
        backend => Cache::FileCache->new({
            namespace => 'html_cache',
            max_size  => 10 * 1024 * 1024,
        }),
        expires_min => 3,
        expires_max => 60,
        check_load  => sub {
            my $entry = shift;
            int($entry->{process_time} * 2) - 1;
        },
    });
}基本、こんな感じで初期化するのですが、別のprofileを登録しておく事が出来ます。
$self->cache_adaptive('another_profile', $cache_adaptive);これは後でprofileの選択が出来ると言う事です。
Cacheable code attribute
    内部的にはソースを見て頂ければ分かる通り、Attribute::Handlersを使っています。
    このモジュールを使うと比較的簡単にattributeによる拡張が出来ます。
  
Cacheable attributeで指定出来るkey_fromパラメータですが、下記の値を設定出来ます。
- path
- query
- path_info
- session
特に今回はsessionと言う指定もあるように、session_idによって異なる結果が返って来るようなケースでも期待通りsession_idごとにキャッシュが適用出来るようにしました。
sub do_user_page : Cacheable(qw/path path_info session/) {
    ### process per user
} ちなみに指定があるkeyの種(path, query, path_info, session)とそれらの実際の値をHASHREF化して、Storableのfreeze使ってシリアライズした物をkeyとしているので、これらの値を組み合わせてユニークな値であればCache時のkeyもユニークになります。
雑多なtips/BK
作ってる最中に幾つか覚えた事とかハマった事などです。
- mod_perlとINIT, CHECK
- mod_perl化だとINIT, CHECKフェーズが存在しないようです。(少なくともAttribute::Handlersの指定はスルーされてます。) 従って事実上、BEGINフェーズに引っ掛けるしかありません。
- CGI::Applicationのリアルなテスト
- 
      Test::WWW::Mechanize::CGIを使いましょう。
      ほとんど実際に動かしているのと同じようなテストが出来ます。$ENV{CGI_APP_RETURN_ONLY}によるテストは小学生まで。
 当然、CGI::Applicationだけでなく、cgiとして動作させる物ならばなんでも適用可能です。
- 安易なシンボルテーブル操作はミスの元w
- 
      と言うか元々シンボルテーブルにアクセスして、書き換えてみたり、そのコードリファレンスを取得してゴニョゴニョしたりってのはフレームワーク側でしっかりと枠組みが無いと危険だなぁと。(Catalystと比較)
 CGI::Applicationに関してはpluginによる拡張の規定が緩いので、みんな好き勝手書けてしまうのが今回は苦戦の元でした。
 特に今回のようにattributeを使う場合、基本BEGINフェーズでattributeのparseが走って、その後に事前に拡張を仕込むような実装になるのですが、さらに元のCODEREFをwrapするなんて処理が入ると、別にそのCODEREFを利用するようなモジュールがあると凄い大変な事になります。
    まぁとは言え、CGI::Applicationって実にシンプルだなぁと改めて思いました。
    ちょっとしたアプリケーション作るのにCatalystをわざわざ使う必要性は全然無くて、適材適所で判断出来ればいいのかなぁと思います。
  
trackback
- trackback url
- trackback count
- 0

comment