moggs has asked for the wisdom of the Perl Monks concerning the following question:

Greetings Monks

I have a question, probably easy for most but it's got me stumped...

I have a script that runs when called by the browser, as you would normally expect. The problem is that the script needs to respond quickly so the user can go on to other things (due to short user attention spans, etc) then carry on to complete the actual processing and not terminate, which appears to be the case with my simple code at present.

For example:

#!/usr/bin/perl -T print "content-type:text/html\n\n"; print qq~<head> <body> <h1>Thanks, you may go now</h1> </body> </html>~; open (COMPANY,"./data/long_list_of_company_names.txt"); while (<COMPANY>) { # do something really exciting here like create # a report and write it to the web space # do lots of error checking too, not detailed here } close (COMPANY); # no more output, user has gone, but it would maintain a log of activi +ty

I hope this makes the point, because I don't know the correct terms. I've experimented with fork, but can't prove this is working.

Your ideas would be appreciated very much indeed.

moggs!

Replies are listed 'Best First'.
Re: Keeping the script running after the Brower closes
by Joost (Canon) on Aug 15, 2007 at 23:38 UTC
    Hmmm.

    AFAIK as long as you make sure you close STDOUT and STDIN (or at least not use them ever) you should be fine, but the webserver may decide the request is taking too long and terminate it anyway. You can probably fork() a separate process to get around that (make sure you close STDIN and STDOUT before the fork or in the child process, though!)

    update:

    # process input # print HTML page close STDIN; close STDOUT; my $child_pid = fork(); if (!defined $child_pid) { die "Can't fork child process"; } if ($child_pid) { # in parent process exit; } # do long processing here.
    You might need to set some signal handlers and/or close additional filehandles you've opened in the parent process, but as a general outline, this should work.

Re: Keeping the script running after the Brower closes
by oxone (Friar) on Aug 16, 2007 at 06:43 UTC
    If your problem is just that nothing gets sent to the browser until the whole script has finished, you can just insert this line before your first print:
    $|=1; # Send output to browser right away

    However the browser page still won't fully 'finish' until your script does, unless you do a fork.

Re: Keeping the script running after the Brower closes
by CountZero (Bishop) on Aug 16, 2007 at 14:55 UTC
    That is not the way it works.

    Closing the browser does not terminate any scripts on the server. As such the server does not "know" that after sending the message to the client at the beginning of the script, no more output is to follow and even if the browser goes "away" the script keeps running until it finishes.

    The browser does not inform the server to stop working on a previous request when it closes.

    Your problem must therefore be somewhere else, perhaps (as already said by oxone) it is due to buffering problems or may be there is an error in your script which terminates it.

    CountZero

    A program should be light and agile, its subroutines connected like a string of pearls. The spirit and intent of the program should be retained throughout. There should be neither too little or too much, neither needless loops nor useless variables, neither lack of structure nor overwhelming rigidity." - The Tao of Programming, 4.1 - Geoffrey James