[rabbitmq-discuss] librabbitmq-c and amqp_channel_close

Brennan Sellner bsellner at seegrid.com
Fri Jun 22 21:57:51 BST 2012


On 06/22/2012 01:04 PM, Matthias Radestock wrote:
> On 22/06/12 17:19, Brennan Sellner wrote:
>> I don't suppose there's an equivalent async method?
>
> You could just not wait for the close-ok :) That would be quite hard in
> most AMQP client libraries, but perhaps it's possible in librabbitmq.
>
> Also, if you are intending to close the connection too, then *just* do
> that, rather than closing all the channels first. It's semantically
> equivalent(ish).
>
> And in that case, if you really don't care about the various guarantees
> provided by the handshake, you could simply close the socket instead,
> i.e. don't bother with any of the closing handshake. That is not really
> recommended though.
>
>> Failing that, any thoughts on what can be done server-side to speed up
>> the process? Do durable queues/exchanges exacerbate the problem?
>
> Yes.

Okay, thanks much for the feedback!  We're not closing the whole 
connection, so we can't take one of the more scorched-earth approaches: 
we use a channel per subscription to keep a protocol error on one from 
taking down everyone, and the problem arose in the unsubscribing code.

In case it's useful to anyone else, I added the below to amqp_api.c 
(with the appropriate prototype in amqp.h).  It's a Frankenstein of the 
relevant bits of amqp_channel_close and amqp_simple_rpc, and could 
probably be cleaned up a bit / refactored, but this is the minimal diff 
against the existing library.  It seems to work, but only time will 
tell, since the original bug wasn't reliably reproducible.

Thanks for the help,

-Brennan

--------------------------------------

amqp_rpc_reply_t amqp_async_channel_close(amqp_connection_state_t state,
                                           amqp_channel_t channel,
                                           int code)
{
   amqp_rpc_reply_t result;
   int status;
   amqp_channel_close_t req;
   char codestr[13];

   memset(&result, 0, sizeof(result));

   req.reply_code = code;
   req.reply_text.bytes = codestr;
   req.reply_text.len = sprintf(codestr, "%d", code);
   req.class_id = 0;
   req.method_id = 0;

   status = amqp_send_method(state, channel, AMQP_CHANNEL_CLOSE_METHOD,
                             &req);

   if (status < 0) {
     result.reply_type = AMQP_RESPONSE_LIBRARY_EXCEPTION;
     result.library_error = -status;
     return result;
   }

   /* Don't wait for the server to reply; just report everything
    * as A-OK.  The outer loop will need to discard the
    * channel-close-ok frame when it arrives. */
   result.reply_type = AMQP_RESPONSE_NONE;
   return result;
}




More information about the rabbitmq-discuss mailing list