codeminders / php-amqplib

PHP library implementing Advanced Message Queuing Protocol (AMQP).
GNU Lesser General Public License v2.1
0 stars 0 forks source link

stream_set_timeout causes fread loops to spin #6

Closed GoogleCodeExporter closed 9 years ago

GoogleCodeExporter commented 9 years ago
What steps will reproduce the problem?
1. Enable xdebug profiling.
2. Create an AMQPConnection object.
3. Check the number of times AMQPConnection::__construct calls php::fread

What is the expected output? What do you see instead?

A literal reading of the PHP manual's page on stream_set_timeout suggests that 
fread will wait 
*up to* the timeout before returning, and only return early if data becomes 
available. What 
actually happens is that fread($this->sock) in AMQPReader::rawread returns "" 
(empty string) 
immediately on the majority of calls, immediately and without waiting. This in 
turn causes an 
excessive number of fread syscalls, driving up system time and CPU load.

What version of the product are you using? On what operating system?

amqplib trunk r24, on PHP 5.2.6 (Linux 2.6.18-128.1.6.el5 #1 SMP Wed Apr 1 
09:19:18 EDT 
2009 i686 i686 i386 GNU/Linux)

Please provide any additional information below.

Calling fread to read single bytes is also pretty lame. :)

Original issue reported on code.google.com by angrybal...@gmail.com on 8 Sep 2009 at 8:18

GoogleCodeExporter commented 9 years ago
Turns out this is a plain old-fashioned thinko: AMPQConnection::__construct 
takes $read_write_timeout but 
passes $rw_timeout.  See patch.

Original comment by angrybal...@gmail.com on 8 Sep 2009 at 8:22

Attachments:

GoogleCodeExporter commented 9 years ago
As for reading single bytes via fread, this patch adds a simple-minded 
buffering layer to AMQPReader.

Original comment by angrybal...@gmail.com on 8 Sep 2009 at 8:25

Attachments:

GoogleCodeExporter commented 9 years ago
I noticed the amqp_consumer.php takes 100% cpu while waiting for commands. The 
problem 
is in AMQPReader::rawread that loop like crazy to read 1 byte. In the while 
loop I 
added a usleep(100) and it drop the CPU usage to around 50% while maintaining 
good 
performance.

Original comment by benoit.a...@gmail.com on 14 Sep 2009 at 3:34

Attachments:

GoogleCodeExporter commented 9 years ago
100% CPU is a side effect of the bug my first patch (issue-6.patch) above 
fixes. With that sorted out, the number 
of calls to fread drops dramatically, reducing CPU load even without sleeps or 
buffering.

Original comment by angrybal...@gmail.com on 14 Sep 2009 at 10:58

GoogleCodeExporter commented 9 years ago
Oh much better patch!

Thanks!

Original comment by benoit.a...@gmail.com on 18 Sep 2009 at 1:32

GoogleCodeExporter commented 9 years ago
patches are applied

Original comment by lyolik1...@gmail.com on 27 Jan 2010 at 9:11