以前まで Catalyst と DBIx::Class を使って運用していた「YouTubeMP4」というサイトを Plack 、DBIx::Skinny ベースでリライトして先ほどから実運用を始めました。
先日の YAPC::Asia でのセッションを聞いている方はお分かりの通り、 Plack というのは PSGIという仕様 の実装です。 Plack 単体で見れば HTTP::Engine 相当のもので、 HTTP の Request/Response 周りを処理してくれて CGI や mod_perl をはじめ 様々なインターフェースに対して透過的にフレームワークを載せることができます。
この Plack を使って必要最低限な Web Application Framework とも言えるかどうかわからないほどの、 小さな WAF を自分で作り、その上に今回「YouTubeMP4」というアプリケーションを書いたという具合です。 この WAF は「Noe」という名前で github にて公開しています。 ちなみに、tokuhirom が作った「nttam」というこれまた Plack ベースの小さなWAFを参考にして作らせてもらいました。 見ればわかる通り、クラスがたった2つ、行数にして150行以下のものです。 Plack は PSGI の実装という意味の他に、 HTTP::Engine と比べても少ないコードでWAFを構築できるのと今回作っていて感じましたね。
追記: HTTP::Engine と比べてっていうのは、plackup などのユーティリティのおかげなので、 一概に「少ないコードで」というのはちょいと語弊がありますね>< Yappoさんツッコミあざっす。
Noe の少ない機能の内訳は、リクエストされたURIに対してどのコントローラクラスのメソッドを呼び出すかと指示する「ディスパッチャ」、 引数を受け取り Template Toolkit で HTML 化してレンダリングする「ビュー」、 リダレイクトやベースとなるURLを得ることができるメソッド郡となっています。 「モデル」部分はアプリケーション毎に書くというのが一応の作法としています。 Mouse ベース、config ファイルの読み込み、テンプレートの拡張子によってラッパーを働かせるかどうかを指定する、 ディパッチャには HTTPx::Dispatcher を仕様するなど、 個人的な嗜好がかなり入っています。 本当に最小限ですが、「YouTubeMP4」のようないたってシンプルな機能を提供するサービスでは、 これで十分動きます。 参考になるのでしたら github のソースをみてください、そして何かあればツッコミください。
また O/R マッパは nekokak さん作の DBIx::Skinny を使うことにしました。 SQL をやはり書きたくない、けれども DBIx::Class はさすがにヘビーすぎると思っていたところ nekokak さんと話していて薦められたので使ってみたらいい感じです。
今回のリライトでどれほどパフォーマンスが上がったかは、内部のロジックを大幅に変えたために 結果がでないのですが、メモリ消費の観点で言うと約 3分の2 以下になっているのを確認しました。 ちなみに Webサーバには lighttpd を使っています。 今後、YouTubeMP4 と同じように「機能はそこまで必要ではなく、かつ、そこそこアクセスの多い」サービスに関して Noe を使った運用も考えていきたいと思います。
こうした小さいけれども一応「WAF」というものは作るのが2度目なのですが、 アプリケーションサーバの機構について知れることだけではなく、 Perl の黒魔術的な一面も考えなくてはいけなかったり、設計について考えさせられたりと いろいろ勉強になります。 Plack/PSGI の急速な開発にあわせつつも、勉強しながら、改良していくつもりです。 上記した通り何かツッコんでいただければ幸いです。