This guide explains how (and why) applications that use amqp gem versions 0.6.x and 0.7.x should migrate to 0.8.0 and future versions. It also outlines deprecated features and when and why they will be removed.
This work is licensed under a Creative Commons Attribution 3.0 Unported License (including images and stylesheets). The source is available on Github.
This guide covers Ruby amqp gem 0.6.x and 0.7.x.
The amqp gem was born in early July 2008. Since then, it has seen 7 releases, used by all kinds of companies, and has become a key component in systems that process more than 100 gigabytes of data per day. Also, despite not being a “1.0 library”, it has proven to be very usable.
For most of 2008 and 2009 the gem did not receive much of attention. In 2010, some other AMQP clients (for example, RabbitMQ Java & .NET clients) switched to the AMQP 0.9.1 specification. By the fall of 2010 it had become clear that the amqp gem needed a new team of maintainers, deep refactoring, new solid test suite and extensive documentation guides. Long story short, by December 2010, the new maintainers group was formed and now maintains a number of other libraries in the Ruby AMQP ecosystem, most notably the Bunny gem.
Over the first few months of 2011, the amqp gem underwent a number of maintenance releases (known as the 0.7.x series), a ground up rewrite of the test suite, major documentation update as well as a major refactoring. It was upgraded to the AMQP 0.9.1 specification and based on a new, much more efficient AMQP serialization library, amq-protocol.
As part of this transition, the amqp gem maintainers team pursued a number of goals:
In the end, several projects like evented-spec were born and became part of the amqp gem family of libraries. The "300 one patch forks" hell is a thing of the past. Even the initial pure Ruby implementation of the new serialization library was several times as memory efficient as the original one. The response to the Documentation guides response was very positive. amqp gem 0.8.0 implemented all but one RabbitMQ extension as well as AMQP 0.9.1 spec features that the original gem never fully implemented. Many heavy users of the gem upgraded to 0.8 or later versions. The future for the amqp gem and its spin-offs is bright.
amqp gem 0.8.0 is *not 100 backwards compatible. That said, for most applications, the upgrade path is easy. Over 90 of the deprecated API classes and methods are still in place and will only be dropped in the 0.9.0 release.
Plenty of the incompatibilities between the 0.6.x and 0.7.x series were ironed out in 0.8.0. This guide will explain what has changed and why. It will also encourage you to upgrade and show how you should adapt your application code.
amqp gems before 0.8.0 (0.6.x, 0.7.x) series implemented (most of) the AMQP 0.8 specification. amqp gem 0.8.0 implements AMQP 0.9.1 and thus requires RabbitMQ version 2.0 or later. See RabbitMQ versions for more information about RabbitMQ versions support and how to obtain up-to-date packages for your operating system.
amqp gem 0.8.0 and later versions implement AMQP 0.9.1 and thus require RabbitMQ version 2.0 or later
Instead of the following:
require "amqp"
require "mq"
or
require "mq"
switch to
require "amqp"
mq.rb will be removed before 1.0 release.
Please use AMQP::Channel
instead. MQ class and its
methods are implemented in amqp gem 0.8.x for backwards compatibility.
Why is it deprecated? Because it was a poor name choice. Both mq.rb and the MQ class depart from AMQP terminology and make eight out of ten engineers think that they have something to do with AMQP queues (in fact, MQ should have been called Channel in the first place). No other RabbitMQ client library that we know of invents its own terminology when it comes to protocol entities and the amqp gem shouldn’t either.
The MQ class and class methods that use an implicit connection (MQ.queue and so on) will be removed before the 1.0 release.
The MQ class was renamed to AMQP::Channel to follow the established AMQP 0.9.1 terminology. Implicit per-thread channels are deprecated:
# amqp gem 0.6.x code style: connection is implicit, channel is implicit. Error handling and recovery are thus
# not possible.
# Deprecated, do not use.
MQ.queue("search.indexing")
# same for exchanges. Deprecated, do not use.
MQ.direct("services.imaging")
MQ.fanout("services.broadcast")
MQ.topic("services.weather_updates")
# connection object lets you define error handlers
connection = AMQP.connect(:vhost => "myapp/production", :host => "192.168.0.18")
# channel object lets you define error handlers and use multiple channels per application,
# for example, one per thread
channel = AMQP::Channel.new(connection)
# AMQP::Channel#queue remains unchanged otherwise
channel.queue("search.indexing")
# exchanges examples
channel.direct("services.imaging")
channel.fanout("services.broadcast")
channel.topic("services.weather_updates")
MQ.queue, MQ.direct, MQ.fanout and MQ.topic methods will be removed before 1.0 release. Use instance methods on AMQP::Channel (AMQP::Channel#queue, AMQP::Channel#direct, AMQP::Channel#default_exchange and so on) instead.
MQ::Queue is now AMQP::Queue. All the methods from 0.6.x series are still available.
MQ::Queue alias will be removed before 1.0 release. Please switch to AMQP::Queue.
MQ::Exchange is now AMQP::Exchange. All of the methods from the 0.6.x series are still available.
MQ::Exchange alias will be removed before 1.0 release. Please switch to AMQP::Exchange.
MQ::Header is now AMQP::Header. If your code has any type checks or case matches on MQ::Header, it needs to change to AMQP::Header.
Catch-all solutions for error handling are very difficult to use. Automatic recovery and fine-grained event handling is also not possible. amqp gem 0.8.0 and later includes a fine-grained Error Handling and Recovery API that is significantly easier to use in real-world cases but also makes automatic recovery mode possible.
AMQP.error method will be removed before 1.0 release.
It was an experiment that was never finished. Some API design choices are very opinionated as well. The amqp gem should not ship with half-baked poorly designed or overly opinionated solutions.
MQ::RPC class will be removed before 1.0 release.
It was another experiment that was never finished.
MQ::Logger class was removed in the the amqp gem 0.8.0 development cycle.
AMQP::Buffer was an AMQP 0.8 protocol implementation detail. With the new amq-protocol gem, it is no longer required.
AMQP::Buffer class was removed in the the amqp gem 0.8.0 development cycle.
AMQP::Frame was an AMQP 0.8 protocol implementation detail. With the new amq-protocol gem, it is no longer required.
AMQP::Frame class was removed in the the amqp gem 0.8.0 development cycle.
AMQP::Server was (an unfinished) toy implementation of AMQP 0.8 broker in Ruby on top of EventMachine. We believe that Ruby is not an optimal choice for AMQP broker implementations. We also never heard of anyone using it.
AMQP::Server class was removed in the amqp gem 0.8.0 development cycle.
AMQP::Protocol::* classes were an AMQP 0.8 protocol implementation detail. With the new amq-protocol gem, they are no longer required.
AMQP::Protocol::* classes were removed in the the amqp gem 0.8.0 development cycle.