[rabbitmq-discuss] rabbitmq-c: Nonblocking recv

Alan Antonuk alan.antonuk at gmail.com
Thu Feb 16 05:32:06 GMT 2012


I agree with the method used in the gist linked in your email:

First check amqp_frames_enqueued(). If this returns true, there are decoded
frames ready, amqp_simple_wait_frame() will not block.

Second check amqp_data_in_buffer(). If this returns true, there is data
that has already been received (with recv()) but not decoded. It is likely
if you call amqp_simple_wait_frame() it will not block. However if the data
in the buffer doesn't complete a frame, recv() will be called and may block.

Third, call select() or poll() on the socket associated with the connection
(you can use amqp_get_sockfd() to get the socket descriptor). If this
system call shows that the socket can be read from amqp_simple_wait_frame()
will call recv() and likely won't block - assuming a full frame is received.

As you may notice the last two steps don't give you a "correct all the
time" answer to whether amqp_simple_wait_frame() will block or not. In
practice I've found the majority of the time the above works well enough
for RPC-style AMQP messaging for the following two reasons:
1. When the broker sends data - typically it sends it as an entire frame,
if your select() call returns that there is data in the buffer likely you
already have, or soon will have an entire frame ready to be read by recv()
2. AMQP is intended to be run on a low-latency, high-bandwidth LAN, so if
you do get a partial frame when recv is called, within a short time period
you will receive the rest of the frame, otherwise it is likely something
serious has happened and that will cause the whole connection to die at
some point in the near future (possibly time out - which I grant you can
possibly block for a lengthy amount of time).

There is definitely room for improvement in the rabbitmq-c library handles
non-blocking behavior.


On Feb 15, 2012, at 2:28 PM, Brett Cameron wrote:


I'd look at implementing something along the lines of what Alex describes
in the link using select() or poll(). Have cc'd Alan for his consideration
as to how this might best be done. The approach outlined by Alex in the
link is okay, but you could still potentially find yourself hanging on a
blocked read if something bad happened between the initial check for data
available and a read operation. An alternative might be to add a timeout
parameter to the wait_frame call or create a variant of this function that
includes a timeout...


On Thu, Feb 16, 2012 at 7:58 AM, Arun Chandrasekaran <visionofarun at gmail.com
> wrote:

> Hi all,
> How do we make a non blocking recv from librabbitmq?
> amqp_simple_wait_frame blocks if the queue doesn't contain any message.
> Should we call amqp_data_in_buffer() and based on the result call
> amqp_simple_wait_frame or implement a solution like this?
> http://lists.rabbitmq.com/pipermail/rabbitmq-discuss/2011-September/014868.html
> Thanks in advance.
> - Arun
> _______________________________________________
> rabbitmq-discuss mailing list
> rabbitmq-discuss at lists.rabbitmq.com
> https://lists.rabbitmq.com/cgi-bin/mailman/listinfo/rabbitmq-discuss
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.rabbitmq.com/pipermail/rabbitmq-discuss/attachments/20120216/05ca4675/attachment.html>

More information about the rabbitmq-discuss mailing list