Friday, July 02, 2010

"cannot redeclare exchange" error on amqp and RabbitMQ 1.8 - fixed! (at last)

I've been having some trouble with an inherited MacBook Pro, on Leopard (OS X 10.5), trying to get RabbitMQ and the tmm1-amqp gem up and running. The annoying thing is that it was all working fine a few weeks ago, but I ended up having to completely remove MacPorts and do several sudo rm -rf wipeouts and pretty much rebuild the dev environment from scratch. Since then, I re-installed MacPorts and did:
sudo port install rabbitmq-server

After a bit of fiddling about, I got this error (using exactly the same code that worked a few weeks ago):

vendor/gems/tmm1-amqp-0.6.4/lib/mq.rb:225:in `process_frame': PRECONDITION_FAILED - cannot redeclare exchange 'jobs' in vhost '' with different type, durable or autodelete value in AMQP::Protocol::Exchange::Declare on 1 (MQ::Error)

....several hours of frustrating googling later.....

It turns out that I'd innocently upgraded my version of RabbitMQ 1.8, whereas previously I'd had v1.7.2. This is significant because RMQ 1.8 uses AMQP 0.9, whereas v1.7.2 uses AMQP 0.8 - and this matters because I'm using the tmm1-amqp gem to connect to it, and tmm1-amqp v0.6.4 only supports AMQP 0.8...

(HINT - check the files under the protocol directory to see what version your gem supports)

So - time to downgrade RabbitMQ to 1.7.2 then. Should be straightforward, no? Well, no.

It also turns out that the version of Erlang in MacPorts is now R14A - and guess what? RabbitMQ 1.7.2 doesn't build in Erlang R14A

So I had to create a local MacPorts repo (using the very helpful instructions HERE) from the previous checkin of the Erlang R13B4 portfile and point ports at that.

Then, with a sudo port uninstall rabbitmq-server; sudo port install rabbitmq-server @1.7.2, followed by a blat of the mnesia database files:
sudo rm -rf /opt/local/var/lib/rabbitmq/mnesia/rabbit

- and it all works again. YAY!

(PS - I had to port uninstall and re-install rabbitmq-server twice for it to work properly. So that's always worth a try too - I swear MacOS gets more and more like Windows every day.....:)


tonyg said...

It's not quite true that 1.8.0 supports AMQP 0-9-1; it's still speaking 0-8, but has starting folding in some of the 0-9 interpretations of spec corner cases.

The alternative to downgrading is to make sure that your exchange.declares are consistently using the same values for autodelete and durable for the same named exchanges! Think about the alternative: each declaring app thinks the exchange exists with the parameters *it* has chosen, not the parameters chosen by the app that's racing it. The checks 1.8.0 introduces help reduce hard-to-track-down bugs, IMO.

Alistair Davidson said...

Hi tonyg

Thanks for the clarification. Just on that redeclare point, though - I only have one amqp.start call in my app, and it always has exactly the same parameters. It's the only app on my system that uses RMQ, and this was after a clean install.

If there *is* an inconsistent redeclare in my app, I would love to know where it is!

tonyg said...

Hmm. That section of the code got pretty well tested as part of the release preparation, but I suppose there could be some problem with it. You could track down all the declares in your code by changing them one at a time to use different parameters, and taking note of the exception locations in your ruby code.