Plack::Loader::RestarterとPlack::Loader::Shotgun

よく知らないまま、はじめてplackupを使ってみていたのだけど、ちょっと困っていたので何気なく呟いてみたら…

いやー こんなちょっとしたことでも呟いてみるもんですね。tokuhiromさんからも同様のアドバイスいただきました。ありがとうございます。
http://d.hatena.ne.jp/tokuhirom/20091216/1260962843


コード書いて編集するたびにwebアプリを再起動するのは手間なので、自動で変更を反映して立ち上げ直してくれるための仕組みがあると便利。
他にどういうのがあるのかよく分かっていないのだけど、plackupコマンドの場合"-r"というオプションで./lib以下の変更を監視して立ち上げ直してくれる。
ソースを追いかけてみると、どうやらPlack::Runnnerの中でPlack::Loader::*がアプリのloaderとして設定されるようで、"plackup -r"とした場合、Plack::Loader::Restarterが読み込まれるらしい。これはFilesys::Notify::Simpleというモジュールでファイル変更を監視して、変更時に立ち上げ直すという処理をしてくれるらしい。Filesys::Notify::Simpleの中身をみると、Mac::FSEventsがあればそれを使用(Linuxの場合Linux::Inotify2)、ない場合はsleepしつつ2秒毎にフルスキャンしていく、という仕様のようだ。そりゃCPU喰いますね。(Mac::FSEventsがどうやって監視しているのかは知らない。)


ともかく、Mac::FSEventsを入れることでMacBookが熱くなってしまう問題は解決!


もう1つのLoader、Plack::Loader::Shotgunも試してみた。
最近勉強中のCatalystPlack::Loader::Shotgunを使うところまで

$ catalyst.pl Hoge
created "Hoge"
created "Hoge/script"
created "Hoge/lib"

...

Change to application directory and Run "perl Makefile.PL" to make sure your install is complete
$ cd Hoge
$ ./script/hoge_create.pl PSGI
created "/Users/sugyan/Hoge/script/../script/hoge.psgi"
$ mv script/hoge.psgi app.psgi
$ plackup -L Shotgun
HTTP::Server::PSGI: Accepting connections at http://0:5000/

これだけ。

$ plackup -r

と書けば前述のPlack::Loader::Restarterによってlib以下のファイルが編集されるたびに再起動される。
"-L Shotgun"を使う場合、リクエストが来たときに初めてアプリの再起動をするような形になる。ファイル保存するたびに再起動されるようなことはなく、実際にリクエストを送ったときに変更の反映を確認できるようになる。
しかも、最初からモジュールをロードしておくことができるのである程度そこでロードしておけばその分のコストを削減できるらしい。

$ plackup -L Shotgun &
$ ab -n 10 'http://127.0.0.1:5000/'
...
Requests per second:    0.83 [#/sec] (mean)
Time per request:       1205.442 [ms] (mean)
Time per request:       1205.442 [ms] (mean, across all concurrent requests)
...
$ plackup -MMoose -L Shotgun &
$ ab -n 10 'http://127.0.0.1:5000/'
...
Requests per second:    1.05 [#/sec] (mean)
Time per request:       955.393 [ms] (mean)
Time per request:       955.393 [ms] (mean, across all concurrent requests)
...
$ plackup -MMoose -MHoge::Controller::Root -L Shotgun &
$ ab -n 10 'http://127.0.0.1:5000/'
...
Requests per second:    1.57 [#/sec] (mean)
Time per request:       637.344 [ms] (mean)
Time per request:       637.344 [ms] (mean, across all concurrent requests)
...

うまく使えればかなり便利かも…!