Dhananjay
Dhananjay

Reputation:

Apache Server Timeout with an error message "The page cannot be displayed" for a PHP script

I'm trying to redirect output of a simple Perl script to a web browser using PHP. The Perl script sometimes take 2-3 hours to execute and show output to the screen. By this time, I guess Apache Server simply timesout and displays an error message discribed above.

Here is the sample code snipet.

 # The tmpOutput.txt contains output of a Perl script.
 # Read a file using an handle.
$handle = popen("tail -f tmpOutput.txt", 'r');

 # Check if read handle has been allocated properly.
if ($handle) {
    # to prevent the code from hanging up when the response is slow.
    stream_set_blocking($handle, FALSE);

    # Set the stream timeout period to 24 hours i.e. 86400 seconds.
    stream_set_timeout($handle, 86400);

    # Get the available stream meta data information.
    $info = stream_get_meta_data($handle);

    # While there's no end of file, read the file contents and redirect them to standard display.
    while((!feof($handle)) && (!$info['timed_out'])) {
        $buffer = fgets($handle);
        echo "$buffer<br/>\n";
        ob_flush();
        flush();

        $info = stream_get_meta_data($handle);
    }

    # Check if some issue while streaming data.
    if ($info['timed_out']) {
        echo 'Connection timed out!';
    }
}

 # Close the file handle.
pclose($handle);

Upvotes: 0

Views: 1448

Answers (2)

mob
mob

Reputation: 118645

Another possibility is to arrange for your perl script to continuously produce output.

#!/usr/bin/perl
my $heartbeat_pid = fork();
if ($heartbeat_pid == 0) {    # child process to print a newline every 10 minutes
    my $output_freq = 600;
    for (;;) {
        sleep $output_freq;
        print "\n";
    }
}
&the_main_routine_that_takes_a_long_time_to_produce_output();
kill 9, $heartbeat_pid;     # clean up child at end of script

Upvotes: 0

Byron Whitlock
Byron Whitlock

Reputation: 53911

why are you trying to run this thru the web server? You should run this a little differently. The webserver should signal the perl script to start using a startfile or db entry. A wrapper for the script runs on cron and looks for the startfile. when it sees it, it starts the perl process. The perl proc writes to another web accessible file. after your web app signals the perl script to start, it forwards to a page that ajaxes the output of perl file every 1 second using settimeout.

EDIT

Consider using Ajax you don't have to keep a connection open to the server, but instead you hit it with a multitude of requests:

    <script type="text/javascript">
        function getXmlHttp()
        {
                    var xmlHttp;
            try{    
                xmlHttp=new XMLHttpRequest();// Firefox, Opera 8.0+, Safari
            }
            catch (e){
                try{
                    xmlHttp=new ActiveXObject("Msxml2.XMLHTTP"); // Internet Explorer
                }
                catch (e){
                    try{
                        xmlHttp=new ActiveXObject("Microsoft.XMLHTTP");
                    }
                    catch (e){
                        alert("No AJAX!?");
                        return false;
                    }
                }
            }
            return xmlHttp;
        }

        function Ajax(){
        var xmlHttp = getXmlHttp();
        xmlHttp.onreadystatechange=function(){
            if(xmlHttp.readyState==4){
                document.getElementById('logwindow').innerHTML=xmlHttp.responseText;                    
                setTimeout('Ajax()',1000);
            }
        }
        /* NAME OF OUTPUT FILE HERE */
        xmlHttp.open("GET","session.log?" + Math.random(),true);
        xmlHttp.send(null);
        }


        Ajax();
        </script>

Upvotes: 4

Related Questions