From 0d6955f8ae4cb68897ba1126b5518fb3dc290003 Mon Sep 17 00:00:00 2001 From: Marcus Ilgner Date: Thu, 15 Dec 2022 16:11:39 +0100 Subject: [PATCH 1/4] fix: prevent race condition when manually closing channel 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 -- #: TCP connection failed, reconnecting in 5.0 seconds Dec 15 16:39:02 ruby[321979]: W, [2022-12-15T16:39:02.427582 #321979] WARN -- #: Will recover from a network failure (no retry limit)... Dec 15 16:39:02 ruby[321979]: # 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' ``` --- lib/bunny/session.rb | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/lib/bunny/session.rb b/lib/bunny/session.rb index 2a78b263..df19a8bd 100644 --- a/lib/bunny/session.rb +++ b/lib/bunny/session.rb @@ -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) From 786774dc55722998a48819251883b22d8b516966 Mon Sep 17 00:00:00 2001 From: Michael Klishin Date: Fri, 16 Dec 2022 04:33:17 +0400 Subject: [PATCH 2/4] 2.20.0 --- lib/bunny/version.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/bunny/version.rb b/lib/bunny/version.rb index 3f22ccf6..25ef994f 100644 --- a/lib/bunny/version.rb +++ b/lib/bunny/version.rb @@ -2,5 +2,5 @@ module Bunny # @return [String] Version of the library - VERSION = "2.20.0.pre" + VERSION = "2.20.0" end From 4a753a89c1a20094b273ae1ee7c6a75f067314c3 Mon Sep 17 00:00:00 2001 From: Michael Klishin Date: Fri, 16 Dec 2022 04:34:28 +0400 Subject: [PATCH 3/4] Back to dev version --- lib/bunny/version.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/bunny/version.rb b/lib/bunny/version.rb index 25ef994f..88d5b31f 100644 --- a/lib/bunny/version.rb +++ b/lib/bunny/version.rb @@ -2,5 +2,5 @@ module Bunny # @return [String] Version of the library - VERSION = "2.20.0" + VERSION = "2.21.0.pre" end From 108383aebb49827f22adb62c50570668b62d3969 Mon Sep 17 00:00:00 2001 From: Michael Klishin Date: Mon, 19 Dec 2022 16:30:21 +0400 Subject: [PATCH 4/4] Wording --- lib/bunny/session.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/bunny/session.rb b/lib/bunny/session.rb index df19a8bd..011734e6 100644 --- a/lib/bunny/session.rb +++ b/lib/bunny/session.rb @@ -672,7 +672,7 @@ def handle_frame(ch_number, method) ch.handle_method(method) ensure if ch.nil? - @logger.warn "Could not associate Close message with channel. Probably it was already closed." + @logger.warn "Received a server-sent channel.close but the channel was not found locally. Ignoring the frame." else # synchronises on @channel_mutex under the hood self.unregister_channel(ch)