2016-06-30 60 views
1

我有分叉後每個孩子的構造函數的問題。 例如:PSGI - 每個prefork孩子的構造函數

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'] ]; } 

我希望有人一解釋我如何可以像接龍或Feersum (但一個人的prefork服務器工作「唐鳳」告訴我,Feersum這不是好主意對於)

所以 - 感謝你的答案

+0

你的目標不太清楚。你想讓你的應用成爲一個對象嗎? –

+0

對象 - 它只是正確的編碼類型。 但我的目標是找到init-function調用一次後分叉的地方 –

回答

1

你.psgi可能是如此簡單:

my $obj = Myapp->new; 

my $app = sub { 
    my $env = shift; 

    return $obj->call($env); 
}; 

如果與starman一起運行,則每次Starman分叉時都會實例化Myapp,並且將在每個請求上調用您的實例的call方法。這是可行的,因爲默認情況下,你的.psgi文件是由子進程加載的。

如果與starman --preload-app一起運行,Myapp將僅實例化一次(在父級中),並且所有子級將共享相同的實例。這樣做可以節省內存,但是您的應用程序需要注意不要通過使用共享連接來混淆其他兄弟姐妹。有關更多信息,請參閱https://metacpan.org/pod/distribution/Starman/script/starman#preload-app

這裏的另一個想法你.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,此行爲都是一致的。

相關問題