ruby-amqp / bunny

Bunny is a popular, easy to use, mature Ruby client for RabbitMQ
Other
1.39k stars 303 forks source link

Warnings #563

Closed dacto closed 6 years ago

dacto commented 6 years ago

The Bunny library emits LOTS of warnings.

Most warnings are from uninitialized variables.

Below is an annotated version of the ""Hello World" example" from http://rubybunny.info/articles/getting_started.html.

More uninitialized variable warnings are emitted while performing other operations that are not included in the example.

hello-rabbit.rb

def annotate(label, &block)
  line = caller.first.split(":")[1].to_i + 1
  puts "--- start: [#{label}] @ line #{line} ---"
  yield
  puts "--- end: [#{label}] ---\n\n"
end

annotate('require "bunny"') {
  require "bunny"
}

STDOUT.sync = true

connection = nil
channel = nil
queue = nil
exchange = nil

annotate('connection = Bunny.new') {
  connection = Bunny.new
}

annotate('connection.start') {
  connection.start
}

annotate('channel = connection.create_channel') {
  channel = connection.create_channel
}

annotate('queue = channel.queue("bunny.examples.hello_world", :auto_delete => true)') {
  queue = channel.queue("bunny.examples.hello_world", :auto_delete => true)
}

annotate('exchange = channel.default_exchange') {
  exchange = channel.default_exchange
}

annotate('queue.subscribe do |delivery_info, metadata, payload| {...}') {
  queue.subscribe do |delivery_info, metadata, payload|
    puts "Received #{payload}"
  end
  sleep 2
}

annotate('exchange.publish("Hello!", :routing_key => queue.name)') {
  exchange.publish("Hello!", :routing_key => queue.name)
  puts '--- Note: some of the warnings printed to STDOUT here are from queue.subscribe.. ---'
  sleep 2  # let publish settle
}

annotate('sleep 70  # default heartbeat of 60s') {
  sleep 70  # default heartbeat of 60s
}

annotate('connection.close') {
  connection.close
}

Running the script with warnings (ruby -w hello-rabbit.rb) yields:

--- start: [require "bunny"] @ line 9 ---
/<ruby_2.3.1-gems>/bunny-2.11.0/lib/bunny/transport.rb:32: warning: method redefined; discarding old read_timeout=
/<ruby_2.3.1-gems>/bunny-2.11.0/lib/bunny/session.rb:264: warning: method redefined; discarding old port
/<ruby_2.3.1-gems>/bunny-2.11.0/lib/bunny/queue.rb:384: warning: method redefined; discarding old add_default_options
/<ruby_2.3.1-gems>/bunny-2.11.0/lib/bunny/queue.rb:379: warning: previous definition of add_default_options was here
/<ruby_2.3.1-gems>/bunny-2.11.0/lib/bunny/channel.rb:1591: warning: method redefined; discarding old to_s
/<ruby_2.3.1-gems>/bunny-2.11.0/lib/bunny/channel.rb:268: warning: previous definition of to_s was here
--- end: [require "bunny"] ---

--- start: [connection = Bunny.new] @ line 20 ---
/<ruby_2.3.1-gems>/bunny-2.11.0/lib/bunny/session.rb:1121: warning: instance variable @user not initialized
/<ruby_2.3.1-gems>/bunny-2.11.0/lib/bunny/session.rb:261: warning: instance variable @transport not initialized
/<ruby_2.3.1-gems>/bunny-2.11.0/lib/bunny/session.rb:265: warning: instance variable @transport not initialized
/<ruby_2.3.1-gems>/bunny-2.11.0/lib/bunny/session.rb:1121: warning: instance variable @vhost not initialized
/<ruby_2.3.1-gems>/bunny-2.11.0/lib/bunny/session.rb:1285: warning: instance variable @transport not initialized
--- end: [connection = Bunny.new] ---

--- start: [connection.start] @ line 24 ---
/<ruby_2.3.1-gems>/bunny-2.11.0/lib/bunny/transport.rb:291: warning: instance variable @socket not initialized
/<ruby_2.3.1-gems>/bunny-2.11.0/lib/bunny/session.rb:311: warning: instance variable @socket_configurator not initialized
/<ruby_2.3.1-gems>/bunny-2.11.0/lib/bunny/cruby/socket.rb:83: warning: instance variable @__bunny_socket_eof_flag__ not initialized
/<ruby_2.3.1-gems>/bunny-2.11.0/lib/bunny/cruby/socket.rb:50: warning: instance variable @__bunny_socket_eof_flag__ not initialized
/<ruby_2.3.1-gems>/bunny-2.11.0/lib/bunny/cruby/socket.rb:50: warning: instance variable @__bunny_socket_eof_flag__ not initialized
/<ruby_2.3.1-gems>/bunny-2.11.0/lib/bunny/cruby/socket.rb:50: warning: instance variable @__bunny_socket_eof_flag__ not initialized
/<ruby_2.3.1-gems>/bunny-2.11.0/lib/bunny/cruby/socket.rb:83: warning: instance variable @__bunny_socket_eof_flag__ not initialized
/<ruby_2.3.1-gems>/bunny-2.11.0/lib/bunny/cruby/socket.rb:50: warning: instance variable @__bunny_socket_eof_flag__ not initialized
/<ruby_2.3.1-gems>/bunny-2.11.0/lib/bunny/cruby/socket.rb:50: warning: instance variable @__bunny_socket_eof_flag__ not initialized
/<ruby_2.3.1-gems>/bunny-2.11.0/lib/bunny/cruby/socket.rb:50: warning: instance variable @__bunny_socket_eof_flag__ not initialized
/<ruby_2.3.1-gems>/bunny-2.11.0/lib/bunny/cruby/socket.rb:83: warning: instance variable @__bunny_socket_eof_flag__ not initialized
/<ruby_2.3.1-gems>/bunny-2.11.0/lib/bunny/cruby/socket.rb:83: warning: instance variable @__bunny_socket_eof_flag__ not initialized
/<ruby_2.3.1-gems>/bunny-2.11.0/lib/bunny/cruby/socket.rb:50: warning: instance variable @__bunny_socket_eof_flag__ not initialized
/<ruby_2.3.1-gems>/bunny-2.11.0/lib/bunny/cruby/socket.rb:50: warning: instance variable @__bunny_socket_eof_flag__ not initialized
/<ruby_2.3.1-gems>/bunny-2.11.0/lib/bunny/cruby/socket.rb:50: warning: instance variable @__bunny_socket_eof_flag__ not initialized
/<ruby_2.3.1-gems>/bunny-2.11.0/lib/bunny/session.rb:1278: warning: instance variable @heartbeat_sender not initialized
--- end: [connection.start] ---

--- start: [channel = connection.create_channel] @ line 28 ---
/<ruby_2.3.1-gems>/bunny-2.11.0/lib/bunny/reader_loop.rb:34: warning: instance variable @stopping not initialized
/<ruby_2.3.1-gems>/bunny-2.11.0/lib/bunny/reader_loop.rb:34: warning: instance variable @stopped not initialized
/<ruby_2.3.1-gems>/bunny-2.11.0/lib/bunny/reader_loop.rb:34: warning: instance variable @network_is_down not initialized
/<ruby_2.3.1-gems>/bunny-2.11.0/lib/bunny/cruby/socket.rb:50: warning: instance variable @__bunny_socket_eof_flag__ not initialized
/<ruby_2.3.1-gems>/bunny-2.11.0/lib/bunny/cruby/socket.rb:83: warning: instance variable @__bunny_socket_eof_flag__ not initialized
/<ruby_2.3.1-gems>/bunny-2.11.0/lib/bunny/cruby/socket.rb:50: warning: instance variable @__bunny_socket_eof_flag__ not initialized
/<ruby_2.3.1-gems>/bunny-2.11.0/lib/bunny/cruby/socket.rb:50: warning: instance variable @__bunny_socket_eof_flag__ not initialized
/<ruby_2.3.1-gems>/bunny-2.11.0/lib/bunny/reader_loop.rb:34: warning: instance variable @stopping not initialized
/<ruby_2.3.1-gems>/bunny-2.11.0/lib/bunny/reader_loop.rb:34: warning: instance variable @stopped not initialized
/<ruby_2.3.1-gems>/bunny-2.11.0/lib/bunny/reader_loop.rb:34: warning: instance variable @network_is_down not initialized
/<ruby_2.3.1-gems>/bunny-2.11.0/lib/bunny/cruby/socket.rb:50: warning: instance variable @__bunny_socket_eof_flag__ not initialized
/<ruby_2.3.1-gems>/bunny-2.11.0/lib/bunny/session.rb:650: warning: instance variable @last_connection_error not initialized
--- end: [channel = connection.create_channel] ---

--- start: [queue = channel.queue("bunny.examples.hello_world", :auto_delete => true)] @ line 32 ---
/<ruby_2.3.1-gems>/bunny-2.11.0/lib/bunny/cruby/socket.rb:83: warning: instance variable @__bunny_socket_eof_flag__ not initialized
/<ruby_2.3.1-gems>/bunny-2.11.0/lib/bunny/cruby/socket.rb:50: warning: instance variable @__bunny_socket_eof_flag__ not initialized
/<ruby_2.3.1-gems>/bunny-2.11.0/lib/bunny/cruby/socket.rb:50: warning: instance variable @__bunny_socket_eof_flag__ not initialized
/<ruby_2.3.1-gems>/bunny-2.11.0/lib/bunny/reader_loop.rb:34: warning: instance variable @stopping not initialized
/<ruby_2.3.1-gems>/bunny-2.11.0/lib/bunny/reader_loop.rb:34: warning: instance variable @stopped not initialized
/<ruby_2.3.1-gems>/bunny-2.11.0/lib/bunny/reader_loop.rb:34: warning: instance variable @network_is_down not initialized
/<ruby_2.3.1-gems>/bunny-2.11.0/lib/bunny/cruby/socket.rb:50: warning: instance variable @__bunny_socket_eof_flag__ not initialized
--- end: [queue = channel.queue("bunny.examples.hello_world", :auto_delete => true)] ---

--- start: [exchange = channel.default_exchange] @ line 36 ---
--- end: [exchange = channel.default_exchange] ---

--- start: [queue.subscribe do |delivery_info, metadata, payload| {...}] @ line 40 ---
/<ruby_2.3.1-gems>/bunny-2.11.0/lib/bunny/consumer_work_pool.rb:48: warning: instance variable @running not initialized
/<ruby_2.3.1-gems>/bunny-2.11.0/lib/bunny/cruby/socket.rb:83: warning: instance variable @__bunny_socket_eof_flag__ not initialized
/<ruby_2.3.1-gems>/bunny-2.11.0/lib/bunny/cruby/socket.rb:50: warning: instance variable @__bunny_socket_eof_flag__ not initialized
/<ruby_2.3.1-gems>/bunny-2.11.0/lib/bunny/cruby/socket.rb:50: warning: instance variable @__bunny_socket_eof_flag__ not initialized
/<ruby_2.3.1-gems>/bunny-2.11.0/lib/bunny/reader_loop.rb:34: warning: instance variable @stopping not initialized
/<ruby_2.3.1-gems>/bunny-2.11.0/lib/bunny/reader_loop.rb:34: warning: instance variable @stopped not initialized
/<ruby_2.3.1-gems>/bunny-2.11.0/lib/bunny/reader_loop.rb:34: warning: instance variable @network_is_down not initialized
/<ruby_2.3.1-gems>/bunny-2.11.0/lib/bunny/cruby/socket.rb:50: warning: instance variable @__bunny_socket_eof_flag__ not initialized
--- end: [queue.subscribe do |delivery_info, metadata, payload| {...}] ---

--- start: [exchange.publish("Hello!", :routing_key => queue.name)] @ line 47 ---
/<ruby_2.3.1-gems>/bunny-2.11.0/lib/bunny/cruby/socket.rb:83: warning: instance variable @__bunny_socket_eof_flag__ not initialized
--- Note: some of the warnings printed to STDOUT here are from queue.subscribe.. ---
/<ruby_2.3.1-gems>/bunny-2.11.0/lib/bunny/cruby/socket.rb:50: warning: instance variable @__bunny_socket_eof_flag__ not initialized
/<ruby_2.3.1-gems>/bunny-2.11.0/lib/bunny/cruby/socket.rb:50: warning: instance variable @__bunny_socket_eof_flag__ not initialized
/<ruby_2.3.1-gems>/bunny-2.11.0/lib/bunny/cruby/socket.rb:50: warning: instance variable @__bunny_socket_eof_flag__ not initialized
/<ruby_2.3.1-gems>/bunny-2.11.0/lib/bunny/cruby/socket.rb:50: warning: instance variable @__bunny_socket_eof_flag__ not initialized
/<ruby_2.3.1-gems>/bunny-2.11.0/lib/bunny/cruby/socket.rb:50: warning: instance variable @__bunny_socket_eof_flag__ not initialized
/<ruby_2.3.1-gems>/bunny-2.11.0/lib/bunny/cruby/socket.rb:50: warning: instance variable @__bunny_socket_eof_flag__ not initialized
/<ruby_2.3.1-gems>/bunny-2.11.0/lib/bunny/cruby/socket.rb:50: warning: instance variable @__bunny_socket_eof_flag__ not initialized
/<ruby_2.3.1-gems>/bunny-2.11.0/lib/bunny/cruby/socket.rb:50: warning: instance variable @__bunny_socket_eof_flag__ not initialized
/<ruby_2.3.1-gems>/bunny-2.11.0/lib/bunny/reader_loop.rb:34: warning: instance variable @stopping not initialized
/<ruby_2.3.1-gems>/bunny-2.11.0/lib/bunny/reader_loop.rb:34: warning: instance variable @stopped not initialized
/<ruby_2.3.1-gems>/bunny-2.11.0/lib/bunny/reader_loop.rb:34: warning: instance variable @network_is_down not initialized
Received Hello!
/<ruby_2.3.1-gems>/bunny-2.11.0/lib/bunny/cruby/socket.rb:50: warning: instance variable @__bunny_socket_eof_flag__ not initialized
--- end: [exchange.publish("Hello!", :routing_key => queue.name)] ---

--- start: [sleep 70  # default heartbeat of 60s] @ line 53 ---
/<ruby_2.3.1-gems>/bunny-2.11.0/lib/bunny/cruby/socket.rb:50: warning: instance variable @__bunny_socket_eof_flag__ not initialized
/<ruby_2.3.1-gems>/bunny-2.11.0/lib/bunny/reader_loop.rb:34: warning: instance variable @stopping not initialized
/<ruby_2.3.1-gems>/bunny-2.11.0/lib/bunny/reader_loop.rb:34: warning: instance variable @stopped not initialized
/<ruby_2.3.1-gems>/bunny-2.11.0/lib/bunny/reader_loop.rb:34: warning: instance variable @network_is_down not initialized
/<ruby_2.3.1-gems>/bunny-2.11.0/lib/bunny/cruby/socket.rb:50: warning: instance variable @__bunny_socket_eof_flag__ not initialized
--- end: [sleep 70  # default heartbeat of 60s] ---

--- start: [connection.close] @ line 57 ---
/<ruby_2.3.1-gems>/bunny-2.11.0/lib/bunny/cruby/socket.rb:83: warning: instance variable @__bunny_socket_eof_flag__ not initialized
/<ruby_2.3.1-gems>/bunny-2.11.0/lib/bunny/cruby/socket.rb:50: warning: instance variable @__bunny_socket_eof_flag__ not initialized
/<ruby_2.3.1-gems>/bunny-2.11.0/lib/bunny/cruby/socket.rb:50: warning: instance variable @__bunny_socket_eof_flag__ not initialized
/<ruby_2.3.1-gems>/bunny-2.11.0/lib/bunny/reader_loop.rb:34: warning: instance variable @stopping not initialized
/<ruby_2.3.1-gems>/bunny-2.11.0/lib/bunny/reader_loop.rb:34: warning: instance variable @stopped not initialized
/<ruby_2.3.1-gems>/bunny-2.11.0/lib/bunny/reader_loop.rb:34: warning: instance variable @network_is_down not initialized
/<ruby_2.3.1-gems>/bunny-2.11.0/lib/bunny/cruby/socket.rb:50: warning: instance variable @__bunny_socket_eof_flag__ not initialized
/<ruby_2.3.1-gems>/bunny-2.11.0/lib/bunny/session.rb:650: warning: instance variable @last_connection_error not initialized
/<ruby_2.3.1-gems>/bunny-2.11.0/lib/bunny/cruby/socket.rb:83: warning: instance variable @__bunny_socket_eof_flag__ not initialized
/<ruby_2.3.1-gems>/bunny-2.11.0/lib/bunny/cruby/socket.rb:50: warning: instance variable @__bunny_socket_eof_flag__ not initialized
/<ruby_2.3.1-gems>/bunny-2.11.0/lib/bunny/cruby/socket.rb:50: warning: instance variable @__bunny_socket_eof_flag__ not initialized
/<ruby_2.3.1-gems>/bunny-2.11.0/lib/bunny/reader_loop.rb:34: warning: instance variable @stopping not initialized
/<ruby_2.3.1-gems>/bunny-2.11.0/lib/bunny/reader_loop.rb:34: warning: instance variable @stopped not initialized
/<ruby_2.3.1-gems>/bunny-2.11.0/lib/bunny/reader_loop.rb:34: warning: instance variable @network_is_down not initialized
/<ruby_2.3.1-gems>/bunny-2.11.0/lib/bunny/cruby/socket.rb:50: warning: instance variable @__bunny_socket_eof_flag__ not initialized
--- end: [connection.close] ---

Workaround would be to squelch warnings on a case by case basis such as wrapping all Bunny operations like so:

def silence_warnings(&block)
  old = $VERBOSE
  $VERBOSE = nil
  yield
  $VERBOSE = old
end

silence_warnings do
  require 'bunny'
end

# etc...

However, this method cannot squelch the uninitialized variable warnings emitted while idling (which I think is from the heartbeat code). Furthermore, this hides all warnings, legitimate or subjectively otherwise.

Bunny version: 2.11 RabbitMQ version: 3.7.5 Steps to reproduce: run ruby -w hello-rabbit.rb

michaelklishin commented 6 years ago

LOTS of pull requests that address the warnings are welcome.

michaelklishin commented 6 years ago

Some warnings ended up being legit mistakes. Others don't make much sense to me. Instance variables that are initialised in Bunny::Session#initialize, for example, cause a warning in some methods. Perhaps some of those methods are used before the initialisation but some are pretty certainly not invoked in that method, e.g. Bunny::Session#to_s.

dacto commented 6 years ago

I was just about to submit a PR (still writing detailed commit message) about these! :) I'll pull these latest changes and rebase my changes before submitting the PR.

michaelklishin commented 6 years ago

This was addressed to the extent we easily can do it thanks to #564. There are still some socket extension warnings that would require subclassing Socket which we don't really have any reasons to do.