Re: throttle output streamed from a file?

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Richard Lynch wrote:
On Tue, May 9, 2006 11:11 pm, D. Dante Lorenso wrote:
will 'echo' block until the client has consumed the whole $size amount
of data?  If not, how fast will your while loop execute?  If
file_size($big_file1) exceeds 1 TB, does your server end up sucking up
all available memory?  Or does PHP crash after hitting a memory limit?
I can't be 100% certain, but I'm pretty sure the buffering from client
and Apache and PHP for a simple fopen/fead;echo loop is going to
resolve your problems, and take care of blocking.

Yes, almost-for-sure, echo will block "enough" that your won't run out
of RAM.

I have written some test code, and yes it appears that the 'print' statement WILL block if the output buffer is already filled. See this sample code below:

<?php
define('BUFFER_SIZE', 10000);

//----------------------------------------------------------------------
function client_reader() {
   // connect back to ourself
$myurl = "http://".$_SERVER['HTTP_HOST'].$_SERVER['PHP_SELF']."?server=1";
   $reader = fopen($myurl, "r");
// read data indefinitely but at a slow speed
   $count = 0;
   while (true) {
       print "#";
       error_log("read start #".$count++);
       $buffer = fread($reader, BUFFER_SIZE);
       sleep(2);
   }
// all done
   fclose($reader);
}

//----------------------------------------------------------------------
function server_writer() {
   // build a buffer to write
   $buffer = str_repeat("#", BUFFER_SIZE);

   // write our buffer over and over as fast as our client will let us
   $count = 0;
   while (true) {
       error_log("write start #".$count++);
       print $buffer;
   }
}

//----------------------------------------------------------------------
if (isset($_GET["server"])) {
   server_writer();
}
else {
   client_reader();
}
//----------------------------------------------------------------------
?>

If you load this, the client code connect back to itself and as you can see, the writer writes as fast as it is allowed, but the reader will sleep between reads to ensure that the server writer is much faster than the client reader.

And the following code showed up in my server logs:

---------- 8< -------------------- 8< ----------
write start #0
write start #1
write start #2
write start #3
write start #4
write start #5
write start #6
read start #0
write start #7
write start #8
write start #9
write start #10
write start #11
write start #12
write start #13
write start #14
write start #15
write start #16
write start #17
write start #18
write start #19
read start #1
read start #2
read start #3
read start #4
write start #20
write start #21
write start #22
write start #23
write start #24
read start #5
read start #6
read start #7
write start #25
write start #26
write start #27
write start #28
write start #29
read start #8
read start #9
read start #10
read start #11
read start #12
read start #13
read start #14
read start #15
read start #16
write start #30
write start #31
write start #32
write start #33
write start #34
read start #17
read start #18
read start #19
read start #20
write start #35
write start #36
write start #37
write start #38
write start #39
read start #21
read start #22
read start #23
read start #24
read start #25
read start #26
read start #27
...
---------- 8< ----------

Ok, so, from the looks of it, the server writer seems to block on print when 2MB have filled the output buffer. 2MB is a good number, so I guess I don't need to do anything and everything magically works the way I would expect.

But ... if I wanted to set the output buffer smaller than 2M, like say just 1M or 512K, how would I go about that? Is there a runtime ini_set() value?

Dante

--
PHP General Mailing List (http://www.php.net/)
To unsubscribe, visit: http://www.php.net/unsub.php


[Index of Archives]     [PHP Home]     [Apache Users]     [PHP on Windows]     [Kernel Newbies]     [PHP Install]     [PHP Classes]     [Pear]     [Postgresql]     [Postgresql PHP]     [PHP on Windows]     [PHP Database Programming]     [PHP SOAP]

  Powered by Linux