2

I have this initialiser script for setting my RabbitMq connection using Bunny:

require 'yaml'
config = YAML.load_file('config/rabbitmq.yml')

puts config[Rails.env]
# $bunny = Bunny.new(config[Rails.env])

$bunny = Bunny.new(:host => config[Rails.env]["host"],
         :vhost => config[Rails.env]["vhost"],
         :user => config[Rails.env]["user"],
         :password => config[Rails.env]["password"],
)

$bunny.start
$bunny_channel = $bunny.create_channel

The contents of config[Rails.env] are:

{"<<"=>nil, "host"=>"spotted-monkey.rmq.cloudamqp.com", "user"=>"myuser", "password"=>"mypassord", "vhost"=>"myvhost"}

The verbose syntax of the Bunny.new command works correctly. However, when I comment out the verbose block, and leave this syntax:

$bunny = Bunny.new(config[Rails.env])

I get the following error message:

session.rb:296:in `rescue in start': Could not establish TCP connection to any of the configured hosts (Bunny::TCPConnectionFailedForAllHosts)

I was expecting it to work, since the keys are the same in both cases. Is there any way to call the constructor without specifying each parameter explicitly?

I tried to remove the "<<"=>nil line from the yaml file, with no change in behaviour.

user000001
  • 32,226
  • 12
  • 81
  • 108
  • Hey @user0000001, is this in `application.rb`? – PrimeTimeTran Jan 28 '18 at 12:54
  • I'm not sure what you mean by initialiser script. Maybe I'm mistaken and it's in `config/initializers`? – PrimeTimeTran Jan 28 '18 at 12:55
  • 1
    @PrimeTimeTran: Yes, it was a script in `config/initializers`, that initializes the bunny connection. If you use the same script, remove the line `$bunny_channel = $bunny.create_channel` from the initialiser to the consumer to avoid concurrency issues. – user000001 Jan 28 '18 at 13:01
  • I feel ya, thanks for the pointer. Would you mind giving me one more pointer? I have my connection set up using a worker. I consume the message via another worker. This is my code: http://prntscr.com/i6pami I confirm that my rabbitmq.server is on: http://prntscr.com/i6paye There doesn't seem to be any messages being received: http://prntscr.com/i6pb5q This worked fine when I was using CloudAMQP. – PrimeTimeTran Jan 28 '18 at 13:14
  • @PrimeTimeTran: I can't look into it right now, but you could ask a new question with this problem. Be sure to create a good MVCE prior to posting. – user000001 Jan 28 '18 at 13:50

2 Answers2

1

Having look into source code I found this:

def hostnames_from(options)
  options.fetch(:hosts_shuffle_strategy, @default_hosts_shuffle_strategy).call(
    [ options[:hosts] || options[:host] || options[:hostname] || DEFAULT_HOST ].flatten
  )
end

It seems it is expecting a symbol :host not, string 'host' which is practicaly the only difference between two ways you're calling initializer. Try:

config = HashWithIndifferentAccess.new YAML.load_file('config/rabbitmq.yml')
BroiSatse
  • 44,031
  • 8
  • 61
  • 86
1

Probably the implementation of Bunny.new relies on the fact that the options can be accessed via symbol keys, but you get back string keys from YAML.load_file. You can fix that by using Hash#with_indifferent_access

$bunny = Bunny.new(config[Rails.env].with_indifferent_access)
Patrick Oscity
  • 53,604
  • 17
  • 144
  • 168