Intro
Plack::Builder に登録した Middleware がどういう順番で実行されるか。
よくわからなくなってきたので整理。
Plack::Middleware::* の interface
- prepare_app ... アプリの起動時に1度だけ呼ばれる
- call ... リクエストが飛んできた時に呼ばれる
sample 実装
ファイル構成
+-- app.psgi
+-- lib
+-- My
+-- Middleware
+-- Sandbox1.pm
+-- Sandbox2.pm
+-- local
コード
app.psgi
use strict;
use warnings;
use Plack::Builder;
my $app = sub {
warn sprintf "main called";
[ 200, [ 'Content-Type' => 'text/plain' ], [ "Hello PSGI sandbox" ] ];
};
builder {
enable '+My::M::Sandbox1';
enable '+My::M::Sandbox2';
$app;
};
My
package My::M::Sandbox1;
use strict;
use warnings;
use utf8;
use parent 'Plack::Middleware';
sub prepare_app {
my $self = shift;
warn sprintf("%s->prepare_app() called.", __PACKAGE__);
}
sub call {
my ($self, $env) = @_;
warn sprintf("%s->call() called.", __PACKAGE__);
return $self->app->($env);
}
1;
My
package My::M::Sandbox2;
use strict;
use warnings;
use utf8;
use parent 'Plack::Middleware';
sub prepare_app {
my $self = shift;
warn sprintf("%s->prepare_app() called.", __PACKAGE__);
}
sub call {
my ($self, $env) = @_;
warn sprintf("%s->call() called.", __PACKAGE__);
return $self->app->($env);
}
1;
実行 & 実行結果
$ carton exec -I./lib -- plackup
My::M::Sandbox2->prepare_app() called. at lib/My/M/Sandbox2.pm line 11.
My::M::Sandbox1->prepare_app() called. at lib/My/M/Sandbox1.pm line 11.
HTTP::Server::PSGI: Accepting connections at http://0:5000/
[ここで localhost:5000 にアクセス]
My::M::Sandbox1->call() called. at lib/My/M/Sandbox1.pm line 16.
My::M::Sandbox2->call() called. at lib/My/M/Sandbox2.pm line 16.
main called at app.psgi line 4.
Conclusion
- Plack::Middleware::call() は builder で enable した順番に呼ばれる。
- Plack::Middleware::prepare_app() は builder で enable した順番と反対に呼ばれる。
- Plack::Middleware::* が全部呼ばれてから PSGI App が実行される