2016-06-30 26 views
1

Ich habe Frage nach Konstruktor für jedes Kind nach Gabelung. Zum Beispiel:PSGI - Konstruktor für jedes Prefork-Kind

warn "INIT : Parent : ".$$; 
my $stash; 
sub { 
    unless($stash) { 
     warn "init : Child : ".$$; 
     $stash = { 
      dbh => {} 
     }; 
    } 
    return [ 200, ['Content-Type' => 'text/plain'], ['Hello World'] ]; 
} 

Dieser Code funktioniert, aber dies ist eine schlechte Praxis. Ich mag etwas schaffen wie die

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

I jemand hoffe ein mir erklären, wie es durch prefork-Server wie Starman oder Feersum (Aber ein Mann arbeiten kann „Audrey Tang“ sagt mir, dass Feersum es nicht gute Idee dafür)

so - danke für Ihre Antworten

+0

Ihr Ziel ist nicht ganz klar. Möchtest du deine App zum Objekt machen? –

+0

Objekt - es ist nur richtig Art der Codierung. Aber mein Ziel ist es, den Ort zu finden, an dem die Init-Funktion einmal und nachher Forking genannt wird –

Antwort

1

Ihre .psgi, da dies könnten so einfach sein:

my $obj = Myapp->new; 

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

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

Bei Ausführung mit starman wird Myapp bei jeder Starman-Fork instanziiert, und die Methode call Ihrer Instanz wird bei jeder Anforderung aufgerufen. Dies funktioniert, weil Ihre .psgi-Datei standardmäßig von den untergeordneten Prozessen geladen wird.

Bei Ausführung mit starman --preload-app wird Myapp nur einmal (im übergeordneten Zustand) instanziiert, und alle untergeordneten Elemente teilen dieselbe Instanz. Sie können dadurch Speicherersparnisse erzielen, aber Ihre App muss darauf achten, sich nicht mit anderen Geschwistern zu befassen, indem Sie gemeinsame Verbindungen verwenden. Weitere Informationen finden Sie unter https://metacpan.org/pod/distribution/Starman/script/starman#preload-app.

Hier ist eine andere Idee für Ihre .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); 
}; 

Mit diesem Ansatz wird Myapp nicht instanziiert, bis eine Anforderung empfangen wird, aber es instanziiert wird nur einmal pro Kind Prozess. Dieses Verhalten ist konsistent, unabhängig davon, ob --preload-app verwendet wird oder nicht.