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

dax*_*xim 18 perl multithreading 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 seconds\n"]] };
}
my $dsn = 'dbi:blahblah'; # from config file
my $app = main($dsn);
Run Code Online (Sandbox Code Playgroud)

测量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)
Run Code Online (Sandbox Code Playgroud)

测量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)
Run Code Online (Sandbox Code Playgroud)

这种性能是不可接受的,因为初始化发生了几次,尽管有state变量.你是如何做到这一点只发生一次?

Ask*_*sen -1

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