-
Notifications
You must be signed in to change notification settings - Fork 1k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
No exception thrown on channel exception from basic.{publish,ack,nack} #493
Comments
This protocol design decision is likely intentional: all methods that have no response are on the hot path (
This sounds worth investigating. |
I do see your point here. I understand that AMQP protocol works this way.
To sum it up - I think the exception from a channel should be raised to userland code as soon as it appears in the buffer. Regardless on what operation we are trying to perform. We know the channel is closed so why would we allow to operate on it anyway? What would we potentially gain here? Does it make any sense what I say? |
How can this be handled? I have some long-running consumer processes, where based on queue-input, many different publishes are done. If a single channel error (e.g. due to unknown exchange like in this example) occurs, the consumer will silently lose all subsequent publishes. |
Consider the following example:
The
defined_exchange
already exists and theundefined_exchange
does not.First call to
basic_publish
will result in channel exception being reported to the channel by RabbitMQ and channel being closed. The issue I see here is that in userland we have no clue that this has happened and keep on sending new messages. But they will never arrive to the server because channel has already been closed.The same will happen when you have a consumer defined with prefetch grater than 1. Take a look at the following example:
First message is processed and
ack
-ed with an invaliddelivery_tag
. This results in exception being reported to the channel and channel being closed (on the server side). Due to QOS settings there are already other messages in the stream buffer so the library will simply grab the next available message without realizing there was an exception on the channel. The library will eventually figure it out but only after all messages have been already read from the buffer and the next frame that is there, is the exception itself.Both of the behaviors can be dangerous.
First one because your well defined messages will never reach their destination without any apparent reason.
Second one (even though very unlikely) can lead to processing some messages twice when we definitely need to process them only once.
This behavior also presents itself when people are complaining that there is an exception being raised when they already try to close the connection. This is exactly the same problem. We send close message to the server but instead of getting the response we get previously buffered exception from already closed channel.
As a solution would be to throw an exception as soon as it is possible to detect there is an exception waiting in a buffer. I do understand that this may impact performance to some extend but it would provide a "logical" behavior.
Tested on
php-amqplib/php-amqplib v2.6.3
.The text was updated successfully, but these errors were encountered: