取势 明道 优术

作者为 扶 凯 发表

Plack::Runner 和 plackup

plackup 通过执行 PSGI 的应用来开始 PSGI 的服务. 这个脚本只是非常简单的封闭了 Plack::Runner. 其它的所有都是通过 Plack::Runner 来执行.

  1. 解析命令行的参数.
  2. 选择 Loader 的类并实例化 (通过 Plack::Loader 开头名字空间).
  3. 选择服务器的 lib 库 (通过 Plack::Handler 开头名字空间).
  4. 启动 PSGI 的服务器和传给 PSGI 的应用.

Plack::Loader

Loader 负责实例化和运行 PSGI 服务器. 这个 $loader 对象有一些有意思的功能:

  • $loader->guess() 通过命令行的 $ENV 和 %INC 来猜测使用哪个服务器的 lib 库.
  • $loader->load() 实例化这个服务器的 lib 库, 并返回这个服务器 lib 所产生的对象.
  • $loader->run() 启动这个服务器.

这个 Plack::Loader 的名字空间包含下面三种类型的 loader:

  • Plack::Loader::Delayed – 延迟编译 web app , 直到第一个请求到达
  • Plack::Loader::Restarter – 如果文件发现了任何改变, 会重起这个服务器
  • Plack::Loader::Shotgun – 为每个请求都实时 fork 一个编译的 web app 来运行

我们可以通过 plack –loader 来改变 loader.

Plack::Handler

PSGI spec 中告诉我们 PSGI 定义了应用和服务器之间的接口. 因为 PSGI 的 spec 非常的短小, 这个协议很好的解释了应用程序和 Web 服务器是怎么样通信和工作的.

A library in the Plack::Handler 名字空间的 lib 中包含了满足实际应用服务器. This layer contains all the wiggling.

让我们来写一个新的服务器 AngryBrontosaurus, 我想通过 plackup –server AngryBrontosaurus 来执行. 我实现了一个简单的类, 象下面这样:

package Plack::Handler::AngryBrontosaurus
use strict;
use AngryBrontosaurus;
 
sub new {
    my $class = shift;
    bless { @_ }, $class;
}
 
sub run {
    my ($self, $app) = @_;
    AngryBrontosaurus->new->run($app, $self);
}

在这, 我们要保证 AngryBrontosaurus 在Plack::Handler::AngryBrontosaurus 当中正确的实现了 PSGI spec, 我们可以通过 Plack::Test::Suite 来测试.

use Test::More;
use Plack::Test::Suite;
Plack::Test::Suite->run_server_tests('AngryBrontosaurus');
done_testing;

注意在这, Plack::Handler 名字空间包含了几个 PSGI 服务器的类, 象 Plack::Handler::Starman 和 Plack::Handler::Twiggy, 其中也包含一些类象Plack::Handler::Apache2 和 Plack::Handler::FCGI. 很明显 Apache2 是不可能兼容 PSGI , 但通过这个 Plack::Handler::Apache2 层处理后就能兼容 PSGI 的应用.

时序图

有关 Plack::Runner, Plack::Handler, 和 Plack::Loader 相互作用的时序图.

 

 

来了就留个评论吧! 1个评论