2010-08-09 23 views
3

J'ai essayé de résoudre un petit problème pendant un bon moment mais il semble que je ne suis pas capable de le faire.Script CGI perl côté serveur interrompu lorsque le navigateur côté client se ferme

J'ai écrit une page HTML qui appelle un script CGI Perl lors de la soumission d'un formulaire. Cette CGI exécute un certain nombre de tâches côté serveur et j'ai fait que le script imprime les étapes de ces tâches dans un iframe sur la page HTML. La chose est, si le client ferme son navigateur ou sort de la page, le script CGI est interrompu sur le côté serveur.

code HTML:

<form action="/path/to/script.cgi" method="post" enctype="multipart/form-data" target="processing"> 
<p>File to analyse: <input type="file" name="filename" size="50"/></p> 
<p><input type="submit" name="Submit" value="Analyse" /></p> 
</form></font></p> 

<p style="margin-left: 20"><font face="Arial" size="2" color="#000000">Analysing the file may take a while</font></p> 
<iframe name="processing" width="70%" height="300"> 

</iframe> 

script CGI:

my $query = new CGI; 
print $query->header(-type => 'text/plain'); 
function1(); 
function2_takesLongTime($parameter); 
function3(); 

permet donc dire que "function1" est juste de préparer certaines choses pour l'analyse de fichiers (création de dossiers, etc.). "function2" est la grande fonction (peut durer 15 minutes). C'est un programme perl et il y a beaucoup de "prints" qui, en raison de l'en-tête "text/plain" du CGI, sont redirigés dans le iframe de la page html (en n'utilisant pas de tampon $ | dans le programme). httpd est configuré pour que le délai d'expiration soit bien supérieur à 15 minutes, il ne vient donc pas de là. "function3" est le nettoyage.

Si le client reste sur la page html, le script CGI s'exécute parfaitement. si le client est arrêté (par exemple, l'utilisateur ferme la fenêtre), les fonctions 1 et 2 sont exécutées côté serveur, mais le script semble être interrompu par la suite car aucun nettoyage n'est effectué.

J'ai essayé de lancer "function2" en tant que programme indépendant avec une commande système, ou en créant une bibliothèque perl et en appelant la fonction principale de cette bibliothèque, elle se termine toujours de la même manière. Je pensais que peu importe si le client reste ou non sur la page, le script côté serveur continuerait tout le long. Est-ce à cause de l'en-tête "text/plain" du script CGI qui ne peut être retourné au client que le script est interrompu?

Si quelqu'un peut m'aider avec cela, je serais très reconnaissant.

+0

Il semble que le problème provient des commandes d'appel système qui se trouvent dans ma "fonction2". J'ai essayé d'appeler d'autres fonctions qui ne possèdent pas de commandes système et le script CGI s'exécute tout le chemin même si le client ne répond pas. J'ai également essayé de supprimer l'en-tête CGI et le script fonctionne également parfaitement. Je suppose que c'est la combinaison des deux appels système et le fait que le CGI renvoie la sortie standard au client en temps réel qui fait l'erreur se produire ... –

Répondre

3

Vous devez concevoir votre logiciel différemment. Utilisez une sorte de programmation asynchrone, une file d'attente de travail se passera bien, et utilisez le programme CGI uniquement pour mettre un travail dans la file d'attente. Faites la transition en utilisant la bibliothèque que vous avez déjà mentionnée.

Vous ne semblez pas être familier avec le concept, donc je recommande un très simple: Qudo. Dans le cas où vous le trouvez trop restrictif, passez à Gearman, ce qui je pense est le plus populaire dans le monde Perl (voir les interfaces Gearman::XS et Gearman). TIMBOWTDI: Si vous pouvez abandonner complètement l'environnement d'exécution fourni par CGI.pm, voir par exemple. Catalyst's RunAfterRequest.

+0

Merci pour votre réponse Daxim, "TIMTOWTDI": c'est vrai mais mon application est plutôt linéaire. Même si le programme que je cours est assez gros, je n'ai pas vraiment besoin de multi-tâche. De plus, j'aimerais vraiment comprendre ce qui se passe dans mon script CGI. J'ai testé toutes sortes de façons différentes et je suis vraiment curieux de connaître ce problème. J'ai demandé à certains de mes collègues et personne n'a d'idée d'où ça vient. Merci quand même et je vais sûrement jeter un oeil de plus près à Gearman si jamais j'écris une plus grande application! –

+0

Beanstalk est une autre bonne file d'attente; Je l'utilise dans le code de production et il est assez stable, et l'interface Perl est facile à utiliser. – Ether