Welcome to WebmasterWorld Guest from 54.159.50.111

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)

Senior Member

WebmasterWorld Senior Member 10+ Year Member

joined:Feb 12, 2003
posts:1199
votes: 0


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 Sept 4, 2009 (gmt 0)

Administrator

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

joined:Aug 10, 2004
posts:10544
votes: 8


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 Sept 4, 2009 (gmt 0)

Senior Member

WebmasterWorld Senior Member 10+ Year Member

joined:Oct 4, 2001
posts: 1262
votes: 12


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 Sept 4, 2009 (gmt 0)

Senior Member

WebmasterWorld Senior Member 10+ Year Member

joined:Feb 12, 2003
posts:1199
votes: 0


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

Administrator

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

joined:Aug 10, 2004
posts:10544
votes: 8


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 Sept 4, 2009 (gmt 0)

Administrator

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

joined:Aug 10, 2004
posts:10544
votes: 8


[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 Sept 4, 2009 (gmt 0)

Senior Member

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

joined:Nov 28, 2004
posts:7999
votes: 0


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 Sept 5, 2009 (gmt 0)

Administrator

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

joined:Aug 10, 2004
posts:10544
votes: 8


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 Sept 7, 2009 (gmt 0)

Administrator from US 

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

joined:Sept 21, 1999
posts:38048
votes: 12


>without necessarily releasing a response to the browser.

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