Skip to content
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

Channel#wait_for_confirms may hang until it timeouts in case of some channel-level errors #425

Closed
mitio opened this issue Jul 18, 2016 · 4 comments

Comments

@mitio
Copy link
Contributor

mitio commented Jul 18, 2016

I accidentally encountered a case where I did a publish to a channel and then called wait_for_confirms which hung and did timeout because a channel-level error had occurred.

Here is a short example demonstrating the issue:

c = Bunny::Session.new(continuation_timeout: 1_000)
c.start

ch = c.create_channel

ch.confirm_select

x = ch.direct('test-exchange', durable: true)
q = ch.queue('', exclusive: true)
q.bind(x, routing_key: q.name)

# Delete the test exchange to cause a channel-level error
second_channel = c.create_channel
second_channel.exchange_delete(x.name)

puts 'Publishing (to a deleted exchange)...'
x.publish('foobar', routing_key: q.name)

puts 'Waiting for confirms (it will timeout)...'
x.wait_for_confirms

While the example looks like a problem in the application logic, I think there might also be other cases where the channel might be closed by RabbitMQ and that there should be a way to handle such errors using Bunny's public API. I'm looking for such a way, but I haven't found one yet.

If this is expected behavior in Bunny, what's the proper way to do a publish and then wait (blocking the calling thread) until either an error occurred (including the channel being closed by RabbitMQ) or wait_for_confirms returned?

@michaelklishin
Copy link
Member

Please post questions to the mailing list in the future.

@michaelklishin
Copy link
Member

Bunny::Channel#wait_for_confirms has a timeout. It will try to release outstanding continuations on errors but your code has a race condition it cannot do much about: channel.error arriving from a server is asynchronous.

In case Bunny::Channel#wait_for_confirms doesn't throw an exception if a channel is known to be closed, it would be a good idea to do that.

@mitio
Copy link
Contributor Author

mitio commented Jul 18, 2016

I had missed the mailing list, will use it in the future for questions.

wait_for_confirms (wait_on_confirms_continuations) doesn't throw an exception when a channel is known to be closed.

Is it feasible to think about releasing outstanding continuations on errors and channel close frames?

Looking though the code of Channel I did not see how I can handle this error using its existing public API and that's why I opened an issue rather than looked for a mailing list.

@michaelklishin
Copy link
Member

Then please file a specific issue about throwing exceptions on an already closed channel. Server-sent channel.close in response to asynchronous methods (e.g. basic.publish or basic.ack) have to be handled with Bunny::Channel#on_error because there is no response for Bunny to expect.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants