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