如何使 PSGI 程序在每个进程而不是每个线程只执行一次昂贵的初始化?



交叉帖子:http://perlmonks.org/?node_id=1191821

考虑app.psgi

#!perl
use 5.024;
use strictures;
use Time::HiRes qw(sleep);
sub mock_connect {
my $how_long_it_takes = 3 + rand;
sleep $how_long_it_takes;
return $how_long_it_takes;
}
sub main {
state $db_handle = mock_connect($dsn);
return sub { [200, [], ["connect took $db_handle secondsn"]] };
}
my $dsn = 'dbi:blahblah'; # from config file
my $app = main($dsn);

测量plackup(HTTP::Server::PSGI: Accepting connections at http://0:5000/):

› perl -MBenchmark=timeit,timestr,:hireswallclock -E"say timestr timeit 10, sub { system q(curl http://localhost:5000) }"
connect took 3.0299610154043 seconds
connect took 3.0299610154043 seconds
connect took 3.0299610154043 seconds
connect took 3.0299610154043 seconds
connect took 3.0299610154043 seconds
connect took 3.0299610154043 seconds
connect took 3.0299610154043 seconds
connect took 3.0299610154043 seconds
connect took 3.0299610154043 seconds
connect took 3.0299610154043 seconds
2.93921 wallclock secs ( 0.03 usr +  0.06 sys =  0.09 CPU) @ 107.53/s (n=10)

测量thrall(Starting Thrall/0.0305 (MSWin32) http server listening at port 5000):

› perl -MBenchmark=timeit,timestr,:hireswallclock -E"say timestr timeit 10, sub { system q(curl http://localhost:5000) }"
connect took 3.77111188120125 seconds
connect took 3.15455510265111 seconds
connect took 3.77111188120125 seconds
connect took 3.15455510265111 seconds
connect took 3.77111188120125 seconds
connect took 3.64333342488772 seconds
connect took 3.15455510265111 seconds
connect took 3.77111188120125 seconds
connect took 3.85268922343767 seconds
connect took 3.64333342488772 seconds
17.4764 wallclock secs ( 0.02 usr +  0.09 sys =  0.11 CPU) @ 90.91/s (n=10)

此性能是不可接受的,因为尽管state变量,初始化会发生多次。你如何让它只发生一次?

无论出于何种原因,程序thrall在其配置部分中硬编码"loader"参数:

my $runner = Plack::Runner->new(
server     => 'Thrall',
env        => 'deployment',
loader     => 'Delayed',
version_cb => &version,
);
$runner->parse_options(@ARGV);

该字符串"Delayed"是指模块Plack::Loader::Delayed,它延迟了.psgi文件的加载,直到第一个请求到来。这将与您的基准测试结果相匹配。(如果您再次重新运行基准测试而不杀死 thrall,您将看到相同的输出)。

您可以尝试运行thrall -L +Plack::Loader app.psgi,这会将"loader"参数恢复为在Plack::Runner中硬编码的默认值。

这不是Starman--preload-app选项所做的吗?

相关内容

  • 没有找到相关文章

最新更新