[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