[rabbitmq-discuss] AlreadyClosedException always sets hardError and initiatedByApplication to true
steve at rabbitmq.com
Wed Oct 23 11:24:48 BST 2013
There are some subtleties here. Comments in-line:
On 22 Oct 2013, at 17:07, Jonathan Halterman <jhalterman at gmail.com> wrote:
> if you're doing rapid basicPublish calls to a non-existent exchange. Eventually basicPublish fails with an AlreadyClosedException, but this often occurs before the Channel's ShutdownListener is called. So the client has no fair way of avoiding the AlreadyClosedException.
Let's get one thing out of the way first of all.
Basic.Publish is an asynchronous call. Therefore, if the channel is known and open as far as the client is concerned, there is no good reason for the Basic.Publish to fail (or know anything about the exchange's existence) and no way for the client to prevent subsequent Basic.Publish calls until there are replies back from the server. Nor is there any way to stop previously queued consumer actions on that channel from running. Consumers will be driven (eventually) with a handleShutdownSignal() as their last action. Any channel ShutdownListener will also be driven with the ShutdownSignalException passed to it, but asynchronously. Ordering of action and listener call is not enforced by the client.
If a subsequent action on a closed channel is executed, you will get an AlreadyClosedException (sometimes—ought this to be always?) and this is due to an application initiated action (!), and has a channel reference. (It is represented as a hard error, which is probably wrong.)
Given the channel reference you can get the ShutdownSignalException which closed that channel with Channel.getCloseReason().
This also works on Connections.
> So from my perspective, there are a few things I'd prefer to see out of all this:
> - That AlreadyClosedExceptions be allowed to represent channels that were already closed (as seems to be the case with the reference being set to a Channel).
On Channel method calls it does that already, but has hardError set to true, which is sometimes misleading.
> - That an invocation against a Channel that has already been closed does not result in the Connection being closed (as seems to be the case).
It depends on what you mean by 'already closed'. If the client knows it has closed, then yes, I agree with you. If it doesn't (yet) know it has closed (as in the case for a little while after a publish to a non-existent exchange) then it may not be able to throw an exception (yet). It may, though, because some actions are synchronous with server interaction, which means we can tell from the response if something went wrong.
> - That AlreadyClosedExceptions include the Method that originally cased the closure as the shutdown reason (if any), such as 404. This would allow me to determine why a basicPublish fails.
See above: given the object that has closed, you should be able to get the ShutdownSignalException and determine why it closed.
Steve Powell [Cell: +44-7815-838-558] [RabbitMQ, Pivotal]
“L’enfer, c’est les autres.” Sartre
-------------- next part --------------
An HTML attachment was scrubbed...
More information about the rabbitmq-discuss