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

I have a problem with my CGI file that uses sleep(). I want to print one line at a time with 3 second intervals cause it's a poem. Problem is, it waits until half of the script is done before ANYTHING is printed, then it prints line by line every 3 seconds. Why does it wait for half of them to load rather than print out line by line from the beginning?

I have like 30 lines and it takes 40+seconds to load the first half, then it prints right.

#!/usr/bin/perl use warnings; use strict; $|=1; use CGI qw/:standard/; print header; print "line one<br>\n"; sleep(3); print "line two<br>\n"; sleep(3); print "line three<br>\n"; sleep(3); print "line four\n"; print "<br>\n"; sleep(3);

Replies are listed 'Best First'.
Re: cgi with sleep
by maa (Pilgrim) on Apr 01, 2004 at 08:58 UTC

    Hi,

    On option would be not to do the "sleeping" server side... if JavaScript is enabled in the client you could create a JavaScript Array and use the window.setTimeout(ms) function to print the next index of the array every 3 seconds...

    Just a thought - Mark

Re: cgi with sleep
by eserte (Deacon) on Apr 01, 2004 at 09:43 UTC
    Doing this on the server side is unreliable. There may be proxies which defer the transfered output. The browser itself may decide to buffer first. But maybe you can use a nph script? The CGI.pm docs have some information on this topic.
      Probably using of javascript is the best choice here, but we can do something on sever side:
      #!/usr/bin/perl use warnings; use strict; $|=1; use CGI qw/:standard/; print header; print "line one<br>\n"; print ' ' x 4096; sleep(3); print "line two<br>\n"; print ' ' x 4096; sleep(3); print "line three<br>\n"; print ' ' x 4096; sleep(3); print "line four\n"; print "<br>\n"; sleep(3);
        This may force flushing output buffers on some proxies. Some proxies maybe need larger padding. Some browsers (notably older ones) always wait until the whole response is received before rendering.
Re: cgi with sleep
by inman (Curate) on Apr 01, 2004 at 09:54 UTC
    Try adding the current line number as an argument to your CGI and insert a refresh meta-tag in the HTML with the desired delay and the next line number of the poem in the URL.
      That's exactly the ticket. Don't expect to be able to print to a web browser as though it's a terminal window; you just can't do it reliably. Browsers load once, and then sit there. You can't just print, wait awhile, and print again; the browser won't be refreshed.

      But setting a meta-tag to refresh/reload every five seconds, for example, enables you to have multiple opportunities to print. Then it's possible, the CGI programmer to use hidden fields of some sort (or encoded URL's) to keep track of what's been printed and what needs to be printed in the next cycle.

      That way, in the first cycle, you'll print line one. In the second cycle you'll print line one, and line two. And so on.

      Unless you want to fiddle with javascript or flash, that's how you're going to have to handle it.


      Dave