views:

91

answers:

3

Hi I have a perl script (Cgi / Apache / Windows) which executes some programs on the computer, and formats the output for the web. The script takes about 4-5 minutes to completely run.

My problem is that when someone cancels page load (or closes the web browser) while the script is running, the perl process in the server will keep running without doing anything, and keeps the lock on all open files so another script cannot run. The process will never end, and I have to use "End process tree" to end perl.exe and the started subprocesses to be able to re-run the script.

How can I make sure the script will not die like this? (If the script continues to run in the background, and 'quit' when done, it's the best solution)

+4  A: 

First, no CGI script should run for 4 - 5 minutes.

Second, see Watching Long Running Processes with CGI.

Sinan Ünür
A: 

You can detect if your has pressed the stop button by accessing STDOUT. The following code will die on Apache/IIS CGI if the user is no longer waiting for your answer:

eval {
    print STDOUT "foobar" or die "Gone";
};
if ($@) {
    &cleanup;
}
&do_something;

You may want to print something more intelligent...

Note that your 4-5 min script is reserving the Apache child process all to itself until it has finished running. Consider running the script in background and polling results with AJAX.

jmz
+1  A: 

I would say your design pattern is sub-optimal. A CGI script should not be doing any heavy processing. It should be accessing a db, constructing a page, and returning a result. A CGI script should take fractions of a second to run. Apache was not designed with this use case in mind.

If you want to kick of a long processing job then this job should run outside of your webapp stack. Your CGI script can start the job, check it's progess, kill it etc, but not be waiting for it. A user refresh or ajax poll can check the status of a running job.

Richard