Perl PSGI-每个预工作子级的构造函数
我对分叉后每个子级的构造函数都有疑问。 例如:Perl PSGI-每个预工作子级的构造函数,perl,fork,plack,psgi,starman,Perl,Fork,Plack,Psgi,Starman,我对分叉后每个子级的构造函数都有疑问。 例如: warn "INIT : Parent : ".$$; my $stash; sub { unless($stash) { warn "init : Child : ".$$; $stash = { dbh => {} }; } return [ 200, ['Content-Type' => 'text/plain'], ['Hello W
warn "INIT : Parent : ".$$;
my $stash;
sub {
unless($stash) {
warn "init : Child : ".$$;
$stash = {
dbh => {}
};
}
return [ 200, ['Content-Type' => 'text/plain'], ['Hello World'] ];
}
此代码正在运行,但这是一种糟糕的做法。
我想创造这样的东西
package Myapp;
sub new {
my $class=shift;
my $self=bless {
dbh =>{},
}, $class;
}
sub call {
my ($self, $env) = @_;
# body
return [ 200, ['Content-Type' => 'text/plain'], ['Hello World'] ]; }
我希望有人能向我解释一下它是如何通过Starman或Feersum这样的预工作服务器工作的
(但一个叫奥黛丽·邓的家伙告诉我,这不是个好主意)
所以-感谢您的回答您的.psgi可以这么简单:
my $obj = Myapp->new;
my $app = sub {
my $env = shift;
return $obj->call($env);
};
如果使用starman
运行,Myapp
将在每次starman分叉时实例化,并在每次请求时调用实例的call
方法。这是因为默认情况下,.psgi文件由子进程加载
如果使用starman--preload app
运行,Myapp
将只实例化一次(在父级中),并且所有子级将共享同一实例。这样做可能会节省内存,但您的应用程序需要注意不要使用共享连接与其他同级应用程序发生冲突。有关更多信息,请参阅
下面是关于.psgi的另一个想法:
my %objects;
my $app = sub {
my $env = shift;
my $obj;
if ($objects{$$}) {
$obj = $objects{$$};
}
else {
$obj = Myapp->new;
%objects = ($$ => $obj);
}
return $obj->call($env);
};
使用这种方法,
Myapp
在收到请求之前不会实例化,但每个子进程只实例化一次。无论是否使用--preload app
,此行为都是一致的。您的目标不太清楚。你想让你的应用程序成为一个对象吗?对象-它只是一种正确的编码类型。但我的目标是找到init函数在分叉后调用一次的位置