diff --git a/lib/bunny/session.rb b/lib/bunny/session.rb index e6b151dba..b33a51f3a 100644 --- a/lib/bunny/session.rb +++ b/lib/bunny/session.rb @@ -975,7 +975,11 @@ def open_connection @logger.debug "Heartbeat interval negotiation: client = #{@client_heartbeat}, server = #{connection_tune.heartbeat}, result = #{@heartbeat}" @logger.info "Heartbeat interval used (in seconds): #{@heartbeat}" - @channel_id_allocator = ChannelIdAllocator.new(@channel_max) + # if there are existing channels we've just recovered from + # a network failure and need to fix the allocated set. See issue 205. MK. + if @channels.empty? + @channel_id_allocator = ChannelIdAllocator.new(@channel_max) + end @transport.send_frame(AMQ::Protocol::Connection::TuneOk.encode(@channel_max, @frame_max, @heartbeat)) @logger.debug "Sent connection.tune-ok with heartbeat interval = #{@heartbeat}, frame_max = #{@frame_max}, channel_max = #{@channel_max}" diff --git a/spec/higher_level_api/integration/connection_recovery_spec.rb b/spec/higher_level_api/integration/connection_recovery_spec.rb index 6b768e66f..fd7b31c16 100644 --- a/spec/higher_level_api/integration/connection_recovery_spec.rb +++ b/spec/higher_level_api/integration/connection_recovery_spec.rb @@ -186,4 +186,26 @@ def ensure_exchange_binding_recovery(ch, source, destination, routing_key = "") ensure_exchange_binding_recovery(ch, x, x2) end end + + it "recovers allocated channel ids" do + with_open do |c| + q = "queue#{Time.now.to_i}" + 10.times { c.create_channel } + c.queue_exists?(q).should be_false + close_all_connections! + sleep 0.1 + c.should_not be_open + + wait_for_recovery + c.queue_exists?(q).should be_false + # make sure the connection isn't closed shortly after + # due to "second 'channel.open' seen". MK. + c.should be_open + sleep 0.1 + c.should be_open + sleep 0.1 + c.should be_open + end + end end +