2009-03-19 5 views
2

J'ai une application qui fonctionne en utilisant CGI::Fast de Perl.Comment faire pour que l'application CGI :: Fast basée tue kill -HUP?

Fondamentalement mainloop du code est:

while (my $cgi = CGI::Fast->new()) { 
    do_whatever($cgi); 
} 

Maintenant, je voulais ajouter la capacité de tuer, mais sans perturber la demande en cours de traitement. Pour ce faire, j'ai ajouté la manipulation à SIGHUP. Plus ou moins le long des lignes:

my $sighupped = 0; 
$SIG{ 'HUP' } = sub { $sighupped = 1; }; 
while (my $cgi = CGI::Fast->new()) { 
    do_whatever($cgi); 
    exit if $sighupped; 
} 

Ce qui fonctionne vraiment super quand il vient à « processus pas dérangeant lorsqu'il gère demande de l'utilisateur ». Mais, si le processus attend une nouvelle requête, l'exit basé sur sighup ne sera pas exécuté jusqu'à ce qu'il reçoive finalement une requête et la traite.

Y at-il une solution de contournement pour cela? Ce que je voudrais faire pour que le script sorte immédiatement si le HUP (ou un autre signal, il peut être changé) l'atteint en attendant une requête.

Répondre

1

Vous pouvez utiliser la version de bloc de la fonction eval et la fonction alarm d'ajouter un délai d'attente à Fast::CGI. Dans le code ci-dessous, j'ai défini un délai de cinq secondes. Si le délai expire, il reviendra au début de la boucle qui vérifiera si $continue a été réglé à zéro pour le moment. Si ce n'est pas le cas, nous commençons un nouvel objet CGI::Fast. Cela signifie qu'un délai maximum de cinq secondes s'écoulera après l'envoi d'un HUP avant que le code ne commence à s'arrêter s'il attend un nouvel objet CGI::Fast (le délai d'attente n'a aucun effet sur le reste de la boucle).

my $continue = 1; 
$SIG{HUP} = sub { $continue = 0 }; 
while ($continue) { 
    my $cgi; 
    eval { 
     local $SIG{ALRM} = sub { die "timeout\n" }; 
     alarm 5; #set an alarm for five seconds 
     $cgi = CGI::Fast->new; 
     alarm 0; #turn alarm off 
    }; 
    if ([email protected]) { 
     next if [email protected] eq "timeout\n"; #we will see the HUP signal's change now 
     #died for a reason other than a timeout, so raise the error 
     die [email protected]; 
    } 
    last unless defined $cgi; #CGI::Fast has asked us to exit 
    do_stuff($cgi); 
} 

#clean up 
1

Vous pouvez redéclairer vos SIGnals en fonction de l'emplacement du gestionnaire.

Si vous êtes en dehors de fast-cgi en boucle ou à l'intérieur de l'interrogation fast-cgi et donc pas en la boucle d'événement se termine (fondamentalement la valeur par défaut). Si vous êtes dans la logique d'eventloop, attendez que la logique se termine et se termine.

Pardonnez mon manque d'éditeur en ce moment.

$inlogic=0; 
$hupreq=0; 
SIG{SIGHUP}={ exit unless($inlogic); $hupreq=1;} 

while() 
{ 
    $inlogic=1; 
    function(); 
    $inlogic=0; 
    exit if($hupreq); 
} 
Questions connexes