Welcome to WebmasterWorld Guest from 54.167.252.62

Forum Moderators: coopster & jatar k & phranque

Message Too Old, No Replies

How to show output before running a time-consuming routine?

Perl insists on running the whole script before showing the output

     
6:00 pm on Sep 4, 2009 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



I want my cgi script to show the output as soon as the output is ready, but Perl insists on running the whole script before doing so. For example:

print "Content-type:text/html\n\n $output";
[some time-consuming task here]

Perl waits until the time-consuming task is done before showing the output. (And tThere are no more print commands after the time-consuming task by the way.)

I thought I'd get clever and put the time-consuming task into an external file, but that doesn't help:

print "Content-type:text/html\n\n $output";
`perl timeConsumingTask.pl`; # OR
do('timeConsumingTask.pl'); # OR
system('timeConsumingTask.pl');

There's no difference between these. Perl still waits until the external script has run before showing the output. (By the way, I can't try 'exec', because my webhost has disabled it for security reasons.)

I thought I had a clever solution, by redirecting the user to a new page before running the time-consuming task, but that doesn't help either:

open(FILE,'>output.html');
print FILE $output;
close(FILE);

print "Location:http://example.com/output.html\n\n";

do('timeConsumingTask.pl');

Same deal. The time-consuming task runs first before showing the output.

My final idea is to set a flag in a text file along with a list of data to process, and have a cron job run every minute, checking for the flagged file, and then running if it finds the flagged file. But this is really inelegant. I'd rather not have a cron job running every single minute of every single day, and even if it does, it doesn't process the data as quickly as a regular script would. (The data takes about six seconds to process, and when the user goes to the next page, the processed data might not be ready yet. But please please please, let's not get sidetracked about that. Please trust me that the issue above is exactly as I've described it.)

8:46 pm on Sep 4, 2009 (gmt 0)

WebmasterWorld Administrator phranque is a WebmasterWorld Top Contributor of All Time 10+ Year Member Top Contributors Of The Month



what type of server are you using?

have you tried closing the STDOUT output stream?

close (STDOUT);

you may have to run this script using NonParsed Headers [webmasterworld.com].

edit: grammar

[edited by: phranque at 8:56 pm (utc) on Sep. 4, 2009]

8:48 pm on Sep 4, 2009 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



Try the following prior to the output you want to immediately send to the user: $¦ = 1;

That should flush the output buffer.

8:51 pm on Sep 4, 2009 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



Phranque, that one line of code [close(STDOUT);] totally did the trick. Thanks!
8:55 pm on Sep 4, 2009 (gmt 0)

WebmasterWorld Administrator phranque is a WebmasterWorld Top Contributor of All Time 10+ Year Member Top Contributors Of The Month



flush the output buffer

it's certainly worth a try but i think that will send your STDOUT immediately to the server without necessarily releasing a response to the browser.
8:57 pm on Sep 4, 2009 (gmt 0)

WebmasterWorld Administrator phranque is a WebmasterWorld Top Contributor of All Time 10+ Year Member Top Contributors Of The Month



[close(STDOUT);] totally did the trick.

don't remember if i've actually tried that but glad it was that simple.
9:16 pm on Sep 4, 2009 (gmt 0)

WebmasterWorld Senior Member rocknbil is a WebmasterWorld Top Contributor of All Time 10+ Year Member



Another approach:

if ($pid = fork) {
## Parent process, return response to browser
print "Content-type:text/html\n\n $output";
}
else {
## Child process
close (STDOUT);
## [time consuming function]
}

Fork allows heavyweights to process as background processes, allowing the parent process to return an immediate response to the browser.

8:16 am on Sep 5, 2009 (gmt 0)

WebmasterWorld Administrator phranque is a WebmasterWorld Top Contributor of All Time 10+ Year Member Top Contributors Of The Month



Fork allows heavyweights to process as background processes

this was my first thought but i'm guessing if his host has disabled 'exec' then 'fork' is probably disabled as well.
5:47 am on Sep 7, 2009 (gmt 0)

WebmasterWorld Administrator brett_tabke is a WebmasterWorld Top Contributor of All Time 10+ Year Member Top Contributors Of The Month



>without necessarily releasing a response to the browser.

and the server will probably buffer it anyway - especially if compression is turned on...

 

Featured Threads

Hot Threads This Week

Hot Threads This Month