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

Hi monks,
I've been a Perl programmer for a few years, and recently I did some CGI work for the first time, encountering this problem.
I wrote a CGI program that uploads a file and sends it to a background process. Although the process is in the background, it takes a very long time for the page to load. I have added an example of some code that does a similar thing:
#!/usr/bin/perl use strict; use warnings; #calls a program that sleeps for 20 seconds system "perl sleep.pl &"; print "Content-type: text/html\n\n"; print <<END_OF_PAGE; <HTML> <HEAD> <TITLE>Waiting</TITLE> </HEAD> <BODY> <P> Waiting Some more </P> </BODY> </HTML> END_OF_PAGE
This program calls a program that sleeps in the background. However, it still takes 20 secs for the page to load (sleep=20).
My question is why does it take so long, and how can I overcome this obstacle?
Thanks in advance
Guy Naamati (mrguy123)

Mother Superior jump the gun
--John Lennon

Replies are listed 'Best First'.
Re: CGI and Background Processes
by Corion (Patriarch) on May 05, 2008 at 13:36 UTC

    In Watching Long Processes Through CGI, merlyn closes STDOUT in the child process. Maybe that's what keeps your socket connection open until the child has finished too. I think you could force the page to render by closing STDOUT in the parent and then launching the child, but that way, you lose any way to tell the user that launching the child failed. Maybe you can adapt the code merlyn posted to your needs?

      Thanks, I tried to close STDOUT but it didn't help.
      I will take a look at merlyn's code, but I understand this means there is no easy solution.
Re: CGI and Background Processes
by almut (Canon) on May 05, 2008 at 14:34 UTC

    In my experience (at least with Apache) you need to close STDERR in addition to STDOUT, because Apache (or mod_cgi to be more precise) sets up two pipes to the CGI program (STDERR is connected to Apache's error log), which get duplicated when the CGI process forks... If you don't close them before starting the long-running process, Apache will wait for those handles to be closed by that forked process before it finishes the request cycle.

    Preferably start the long-running process via fork/exec, in which case you can conveniently close STDOUT/STDERR after the fork (so the handles remain functional in the main CGI), but before doing the exec.

    (A similar question came up recently, btw.)

      Thanks, it worked
      I still have to decide if this is the way to go, but at least I know that there's a solution
      UPDATE:
      This seems to work. Unfortunately the background process is supposed to print out to a log. Because STDOUT and STDERR are closed, there is no log.
      It seems that I need to think of another option.
        the background process is supposed to print out to a log

        just reopen STDOUT/STDERR to wherever you want to log to (one of them, or both), instead of closing them...

Re: CGI and Background Processes
by Anonymous Monk on May 20, 2015 at 16:10 UTC
    i love perl