我在分叉后对每个孩子的构造函数有疑问。例如:
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这样的Prefork-Server工作(但是一个人"奥黛丽·唐"告诉我,这不是一个好主意)
所以 - 感谢您的答案
您的.psgi可能与此一样简单:
my $obj = Myapp->new;
my $app = sub {
my $env = shift;
return $obj->call($env);
};
如果使用starman
运行,则每次starman forks都会实例化Myapp
,并且每个请求都会调用实例的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
,此行为是一致的。