Skip to content

Commit

Permalink
fix: prevent race condition when manually closing channel
Browse files Browse the repository at this point in the history
In some situations, explicitly calling `Channel#close` might unregister
the channel from the session before the AMQP Close message gets processed.

Backtrace:

```
Dec 15 16:39:02 ruby[321979]: W, [2022-12-15T16:39:02.427534 #321979]  WARN -- #<Bunny::Session:0x48648 app@localhost:5672, vhost=/, addresses=[localhost:5672]>: TCP connection failed, reconnecting in 5.0 seconds
Dec 15 16:39:02 ruby[321979]: W, [2022-12-15T16:39:02.427582 #321979]  WARN -- #<Bunny::Session:0x48648 app@localhost:5672, vhost=/, addresses=[localhost:5672]>: Will recover from a network failure (no retry limit)...
Dec 15 16:39:02 ruby[321979]: #<Thread:0x00007f3c1ae18540 /opt/app/vendor/bundle/ruby/3.0.0/gems/bunny-2.19.0/lib/bunny/reader_loop.rb:35 run> terminated with exception (report_on_exception is true):
Dec 15 16:39:02 ruby[321979]: /opt/app/vendor/bundle/ruby/3.0.0/gems/bunny-2.19.0/lib/bunny/session.rb:1031:in `block in unregister_channel': undefined method `number' for nil:NilClass (NoMethodError)
Dec 15 16:39:02 ruby[321979]:         from /opt/app/vendor/bundle/ruby/3.0.0/gems/bunny-2.19.0/lib/bunny/session.rb:1030:in `synchronize'
Dec 15 16:39:02 ruby[321979]:         from /opt/app/vendor/bundle/ruby/3.0.0/gems/bunny-2.19.0/lib/bunny/session.rb:1030:in `unregister_channel'
Dec 15 16:39:02 ruby[321979]:         from /opt/app/vendor/bundle/ruby/3.0.0/gems/bunny-2.19.0/lib/bunny/session.rb:675:in `ensure in handle_frame'
Dec 15 16:39:02 ruby[321979]:         from /opt/app/vendor/bundle/ruby/3.0.0/gems/bunny-2.19.0/lib/bunny/session.rb:675:in `handle_frame'
Dec 15 16:39:02 ruby[321979]:         from /opt/app/vendor/bundle/ruby/3.0.0/gems/bunny-2.19.0/lib/bunny/reader_loop.rb:92:in `run_once'
Dec 15 16:39:02 ruby[321979]:         from /opt/app/vendor/bundle/ruby/3.0.0/gems/bunny-2.19.0/lib/bunny/reader_loop.rb:39:in `block in run_loop'
Dec 15 16:39:02 ruby[321979]:         from /opt/app/vendor/bundle/ruby/3.0.0/gems/bunny-2.19.0/lib/bunny/reader_loop.rb:36:in `loop'
Dec 15 16:39:02 ruby[321979]:         from /opt/app/vendor/bundle/ruby/3.0.0/gems/bunny-2.19.0/lib/bunny/reader_loop.rb:36:in `run_loop'
```
  • Loading branch information
milgner committed Dec 15, 2022
1 parent 5dca390 commit 0d6955f
Showing 1 changed file with 6 additions and 2 deletions.
8 changes: 6 additions & 2 deletions lib/bunny/session.rb
Original file line number Diff line number Diff line change
Expand Up @@ -671,8 +671,12 @@ def handle_frame(ch_number, method)
# avoid doing that while holding a mutex lock. MK.
ch.handle_method(method)
ensure
# synchronises on @channel_mutex under the hood
self.unregister_channel(ch)
if ch.nil?
@logger.warn "Could not associate Close message with channel. Probably it was already closed."
else
# synchronises on @channel_mutex under the hood
self.unregister_channel(ch)
end
end
when AMQ::Protocol::Basic::GetEmpty then
ch = find_channel(ch_number)
Expand Down

0 comments on commit 0d6955f

Please sign in to comment.