pika/pika — pull request #456 by jonkirsch (2014-04-04 15:24:04+00:00)
Title: Fix _handle_write() may not send full frame

In _handle_write(), if socket.send does not send all of the requested bytes, put the remainder back
onto the outbound buffer.

In 0.9.13, the frame was popped off of the outbound buffer, and only a single send was done. If all of the bytes could not be sent, the remainder of the frame would never be sent, because it was already popped off of the outbound buffer.

In the current master, sending is done within a while loop. However, the first time the send is tried when the send buffer is full, a WOULDBLOCK would be returned. This error is caught and ignored, but as the frame has already been completely popped off of the outbuffer and never put back on, the remainder of the frame will still never be sent.

In this patch, we try sending once and check if the number of bytes sent is less than the full frame size. If so, we put the remainder of the frame back onto the outbuffer so that handle_events will not clear the WRITE flag. When the socket is ready for writing again, we will send the remainder of the frame (or as much as we can).

I was able to exercise the bug in 0.9.13 and the current master by sending large messages (on the order of 50,000 bytes) to a rabbit running within a VM (i.e., not via loopback), using the tornado adapter. In my tests, the patch fixes the bug.