Dear fellow monks,

the problem I have is already discussed in several places in the internet. However, although I read web pages for hours and tried at least half a dozen suggestions I couldn't manage to get it solved.

The problem is this: I have a CGI script, from which a time-consuming job is started. I don't want to let the user wait for minues, being insecure whether the job has crashed or is running. So when the request to the CGI script is started, I fork the process and let the child create a web page which is regularly refreshed, displaying the elapsed time, while the parent runs its long task. The parent finally creates a file, and this is the signal for the self-refreshing "waiting" HTML page created by the child to switch to a "results" HTML page. In principle this already works fine - only that the child doesn't die after the initial creation of the "waiting" HTML page: it's hanging, until the parent has finished its job and died, and THEN is refreshing - and immediately jumping to the "results" HTML page.

The problem, I guess, is obvious: I didn't make the child entirely independent from the parent, so that the web server still waits for data to arrive until the parent has died. But I found no means to break this dependency. Who can help me?

Because I think that this way it will be easier to track the problem, and my little demo program might be of interest for others with the same intention I'll post the entire little demo program (demo.cgi) here, although it's pretty long for a posting. I hope I don't strain anybodys patience.

Many thanks for your help!

Best greetings and wishes,
Yours
chanklaus


Here's the code for the small demo program. It should work the way I post it here - except for my problem. The only thing still to be changed by you before you can use the program is to adapt the absolute path defined in '$TmpAbs', which I had to symbolize through 'WEBSERVER'. The long job run in the parent is mimicked here by a "sleeping" time lastling for as many seconds as there are "Ticks" defined in the input form of the start page.

#!/usr/bin/perl -w require 5.004; use strict; my (@Query,$CGIPath,$TmpAbs,$TmpVrt,$HtmOut,$HtmTmp); my ($HtmName,$Status,$ForkVal,$STime,$Elapsed,$Ticks,$Prg,$QI); $Prg = "demo.cgi"; @Query = split(/&/,$ENV{'QUERY_STRING'}); $CGIPath = $ENV{'SCRIPT_NAME'}; while (chop($CGIPath) ne "/") { } $TmpAbs = "/www/WEBSERVER/htdocs/tmp"; $TmpVrt = "/tmp"; $HtmName = "demo.html"; $HtmOut = sprintf("%s/%s",$TmpAbs,$HtmName); $HtmTmp = sprintf("%s/%s.tmp",$TmpAbs,$HtmName); for ($QI=0;$QI<=$#Query;++$QI) { if ($Query[$QI] =~ /^Time=/) { ($STime) = ($Query[$QI] =~ /Time=(.*? +)$/); } elsif ($Query[$QI] =~ /^Tick=/) { ($Ticks) = ($Query[$QI] =~ /Tick=( +.*?)$/); } elsif ($Query[$QI] =~ /^STAT=/) { ($Status) = ($Query[$QI] =~ /STAT= +(.*?)$/); } } if (!defined($Status)) { $Status = 0; } #---- If "Start Page" is selected ---------- if ($Status == 0) { &StartPage; } #---- If "Processing" is selected ---------- elsif ($Status == 1) { if (!open(HTMFILE,">$HtmTmp")) { &ErrorMsg(1,$HtmTmp); } $ForkVal = fork(); if (!defined($ForkVal)) { &ErrorMsg(0,""); } if ($ForkVal == 0) { $Elapsed = "00:00:00"; &WaitingPage(sprintf("%s/%s?STAT=2&Time=%s",$CGIPath,$Prg,&CurrTim +e)); close(STDOUT); close(STDERR); close(STDIN); exit(0); } else { print HTMFILE &ProcessPage; close(HTMFILE); system("mv $HtmTmp $HtmOut"); } } #---- If "Waiting Page" is selected ---------- elsif ($Status == 2) { $Elapsed = &ElapsedTime; if (-s $HtmOut) { &WaitingPage(sprintf("%s/%s",$TmpVrt,$HtmName)); } else { &WaitingPage(sprintf("%s/%s?STAT=2&Time=%s",$CGIPath,$Prg,$ST +ime)); } exit(0); } sub ErrorMsg { my ($Stat,$Mess) = @_; print "Content-type: text/html \n\n"; print "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.0 Transitional//EN +\">\n\n<html>\n"; print "<head>\n <title>DEMO Error Message</title>\n</head>\n\n"; print "<body>\n<center>\n\n"; print "<span style=\"font-size:22pt; color:Green\">DEMO ERROR MESSAG +E</span><br>\n<br>\n"; if ($Stat == 0) { print "!!! System error - could NOT fork process ! +!!<br>\n"; } elsif ($Stat == 1) { print "!!! System error - could NOT write \"HTM +L\" file '$Mess'!!!<br>\n"; } print "</center>\n</body>\n</html>\n"; exit(0); } sub StartPage { print "Content-type: text/html \n\n"; print "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.0 Transitional//EN +\">\n<html>\n"; print "<head>\n <title>DEMO START PAGE</title>\n</head>\n\n"; print "<body>\n<center>\n<br>\n"; print "<span style=\"font-size:22pt; color:Green\">DEMO START PAGE</ +span><br>\n<br>\n"; print "<form action=\"$CGIPath/demo.cgi\" method=\"get\">\n"; print "<input type=\"hidden\" name=\"STAT\" value=\"1\">\n"; print "<b>TYPE A &quot;TICK NUMBER&quot;:</b><br>\n"; print "<input type=\"text\" name=\"Tick\" size=\"10\"><br><br>\n"; print "<input type=\"submit\" value=\"PROCESS\"> <input type=\"reset +\" value=\"RESET FORM\">\n"; print "</form>\n</center>\n</body>\n</html>\n"; } sub ProcessPage { my $Html = "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.0 Transitiona +l//EN\">\n<html>\n"; $Html .= "<head>\n <title>DEMO PROCESS PAGE</title>\n"; $Html .= " <meta HTTP-EQUIV=\"Expires\" CONTENT=\"NOW\">\n</head>\n +\n"; $Html .= "<body>\n<center>\n<br>\n"; $Html .= "<span style=\"font-size:22pt; color:Green\">DEMO PROCESS P +AGE</span><br>\n<br>\n"; $Html .= "<span style=\"font-size:22pt; color:Violet\">...THAT'S THE + TEST...</span><br>\n<br>\n"; $Html .= "...<a href=\"$CGIPath/demo.cgi\">go back to the DEMO start + page</a>...<br>\n"; $Html .= "</center>\n</body>\n</html>\n"; sleep($Ticks); $Html; } sub WaitingPage { my ($Url) = @_; print "Content-type: text/html \n\n"; print "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.0 Transitional//EN +\">\n<html>\n"; print "<head>\n <title>...DEMO is running...</title>\n"; print " <META HTTP-EQUIV=\"refresh\" content=\"2; url=$Url\">\n</he +ad>\n\n"; print "<body>\n<center>\n<br>\n"; print "<span style=\"font-size:22pt; color:Red\">...DEMO is running. +..</span><br>\n"; print "<br>\n<span style=\"font-size:22pt\">Don't go BACK!</span><br +>\n<br>\n"; print "<span style=\"font-size:20pt; color:Blue\">Elapsed Time: $Ela +psed</span><br>\n"; print "</center>\n</body>\n</html>\n"; } sub CurrTime { my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime +(time); my $LocTime = "$mday $mon $year $wday $yday $isdst"; $LocTime = sprintf("%02d:%02d:%02d",$hour,$min,$sec); $LocTime; } sub ElapsedTime { my ($Sec,$Min,$Hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime +(time); my $CTime = "$mday $mon $year $wday $yday $isdst"; $CTime = ((($Hour * 60) + $Min) * 60) + $Sec; ($Hour,$Min,$Sec) = split(/:/,$STime); my $ITime = ((($Hour * 60) + $Min) * 60) + $Sec; if ($CTime < $ITime) { $CTime += 86400; } my $ETime = $CTime - $ITime; $Sec = $ETime % 60; $ETime = ($ETime - $Sec) / 60; $Min = $ETime % 60; $Hour = ($ETime - $Min) / 60; $ETime = sprintf("%02d:%02d:%02d",$Hour,$Min,$Sec); $ETime; }
[download]
Remark: Normally I comment (almost) every code line, and I did it as well here, but I couldn't find out how it's done without creating a mess in the posting. However, if someone would like to have the commented code I'd gladly send it to her/him.



Learning is like swimming against the current - as soon as you stop you'll drift back
(Chinese proverb)

In reply to PERL CGI - waiting page is hanging by chanklaus

Title:
Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post, it's "PerlMonks-approved HTML":



  • Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
  • Titles consisting of a single word are discouraged, and in most cases are disallowed outright.
  • Read Where should I post X? if you're not absolutely sure you're posting in the right place.
  • Please read these before you post! —
  • Posts may use any of the Perl Monks Approved HTML tags:
    a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, details, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, summary, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
  • You may need to use entities for some characters, as follows. (Exception: Within code tags, you can put the characters literally.)
            For:     Use:
    & &amp;
    < &lt;
    > &gt;
    [ &#91;
    ] &#93;
  • Link using PerlMonks shortcuts! What shortcuts can I use for linking?
  • See Writeup Formatting Tips and other pages linked from there for more info.