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

Hello,

I'd like to be able to start a perl script that takes up to 20 minutes to run from a web page. The user will click a button, which will run a cgi script that starts the perl script in the background. The cgi script would print that the job has started and the browser connection will cease to be. Here is what I have so far. The background job is started, but the browser keeps the connection to the server open and sits there "transfering from server." How can I get this to work? Thanks for any pointers, ideas, help.

#!/usr/bin/perl use warnings; use strict; use CGI qw(:standard); use CGI::Carp qw(warningsToBrowser fatalsToBrowser); print header; print start_html; my $pid; if ($pid = fork) { print "parent process\n"; } else { print "child process\n"; print end_html; exec('/scripts/run/fsscan 2>&1'); exit 0; }

Replies are listed 'Best First'.
Re: Run perl script from web page
by kyle (Abbot) on May 23, 2007 at 18:48 UTC
      I believe the problem I'm having is with the HTTP server I am using. I'm using pico server (pserv.sourceforge.net). I just tried running similar code on a Linux machine I have Apache running on and it's not a problem there. I was using pico server to just have a lightweight server for serving one page internally on our network.

      Thanks for your help.
Re: Run perl script from web page
by blazar (Canon) on May 23, 2007 at 21:12 UTC
    I'd like to be able to start a perl script that takes up to 20 minutes to run from a web page. The user will click a button, which will run a cgi script that starts the perl script in the background.

    It was asked very recently: once in the referenced node, and ISTR at least yet another time yesterday or the day before - but I can't seem to find where. The usual article by merlyn should have been mentioned there too.

    Update: found!

Re: Run perl script from web page
by leocharre (Priest) on May 23, 2007 at 21:56 UTC

    Yeah, seriously look at perl function fork(). It clones you and keeps going.

    Is what you're doing taking usr input? If not, maybe this can be set up on crontab- a lot of accounts have this- not sure with 'pico'.

Re: Run perl script from web page
by graff (Chancellor) on May 24, 2007 at 01:42 UTC
    I hope the replies above are helpful. This is not a situation that I've had to face, but looking at your code, and thinking about the situation in general, I wanted to raise some points:
    • If the indenting is fixed in your code snippet (yes, proper indentation really helps), it looks like "end_html" is only invoked in the child, which seems wrong (but I'm not well acquainted with CGI scripts launching child processes and exiting cleanly).

    • There's an "exit(0)", but only in the child, after the "exec" call, which of course does not return, so the "exit(0)" is never actually reached. (You say that "similar code" worked on a linux/apache setup -- I'd be a little surprised if this exact code snippet worked anywhere.)

    • If the "fsscan" process is really heavy weight and lengthy, what would happen to your server if some clever hacker were to poke at this web page, say, 50 times in the span of one minute? Wouldn't you want some sort of safe-gaurd (e.g. a known pid file for the fsscan app when it's launched from the web) to keep from having multiple instances running at once?
    There are other issues that I'd expect to arise, but again, I'm not that familiar with the issues... things like zombie processes (parents going away and leaving unreaped children behind).

    On the whole, I'm thinking there must be a better way to actually run this process, other than launching it directly from a cgi script -- e.g. as suggested in a previous reply, you could have a cron process running every few minutes or so, to check whether a request has come in to run fsscan and if so, go ahead and run it (and don't accept any more requests until that run is finished). Then all the cgi script has to do is write some little file somewhere to indicate that such a request has been made.

      All very good points. Thank you very much. As I posted previously, I found that the problem was with the pico http server I was using. I tried similar code on my home Linux box running Apache and it worked fine. I do like the cron idea especially and will look at implementing it. As far as security, this particular server is not accessible from the Internet. It's for internal use only.

      Thanks again!