The Bunny 0.9.x series marks the start of some major improvements in this Ruby AMQP client. This post is a gentle introduction to the Bunny 0.9.x world.
As I write, the Bunny 0.9.x series has started with preview releases. In order to get the current preview release you need to enter the following in the terminal –
gem install bunny --pre
The gem that will be installed will have a version number that looks like 0.9.0.pre[n], where n is the number of the preview. If you enter –
gem install bunny
you will get the current stable release. The first stable release of 0.9.x will be 0.9.0. It will be made available after users have had a chance to try out the preview releases and any issues that are discovered have been addressed.
Next, I’ll take you through a simple example program so that you can get a feel for how 0.9.x works. If you want to try this code yourself, then you will need to have installed a recent version (>= 2.0.0) of RabbitMQ. Existing Bunny users should find very few breaking changes between the syntax of the 0.9.x Bunny API and that of previous versions, but there is additional functionality that is now exposed in more useful ways.
Let’s start the example. First, include the Bunny gem –
Then instantiate a Bunny::Session object which will handle our connection to the RabbitMQ server –
conn = Bunny.new
Now we start a communication session –
At this point we have the option of explicitly declaring a channel. If you are unsure about AMQP channels then you can find a brief explanation here. I say that this channel declaration step is optional because the start method above basically does two things: it opens a connection to RabbitMQ via a TCP socket and creates a default channel that you can use implicitly.
chann = conn.create_channel
Alternatively, you can use the following syntax –
chann = conn.channel
The next step is to declare a queue –
q = chann.queue("test1")
Notice that the queue declaration happens via a channel. In previous versions of Bunny, channels were somewhat hidden, however, in 0.9.x they are much more prominent. If you did not explicitly declare a channel you can use a convenience method in Bunny::Session to declare the queue –
q = conn.queue("test1")
Now we need an exchange to send messages to. We will use the default direct exchange which is bound to all queues –
exch = chann.default_exchange
Again, if you did not declare a channel you can use the following convenience method to get hold of the default exchange –
exch = conn.exchange("")
OK, now we can publish a message to the exchange which then gets routed to the test1 queue –
exch.publish("Hello, everybody!", :routing_key => 'test1')
Something to be aware of here is that there is a :routing_key argument that is synonymous with the :key argument used in previous Bunny versions. You can use either argument to achieve the same thing, so you could also write –
exch.publish("Hello, everybody!", :key => 'test1')
Right, let’s get the message from the queue –
_, _, msg = q.pop
In previous Bunny versions Bunny::Queue#pop returned a hash. In 0.9.x an array (triple) is returned. If you want to get a hash as in previous versions then you need to use the Bunny::Queue#pop_as_hash method –
msg = q.pop_as_hash[:payload]
Now we display the message that we just popped off of the queue –
puts "This is the message: " + msg + "\n\n"
Finally, we close the connection which will also close any channels that we have opened –
Here are two variants of this example in full: the first uses an explicitly declared channel and the second does not.
Example version 1
require "bunny" conn = Bunny.new # start a communication session with the AMQP server conn.start # declare a channel chann = conn.create_channel # declare a queue q = chann.queue("test1") # declare default direct exchange which is bound to all queues exch = chann.default_exchange # publish a message to the exchange which then gets routed to the queue exch.publish("Hello, everybody!", :routing_key => 'test1') # get message from the queue _, _, msg = q.pop # display the message puts "This is the message: " + msg + "\n\n" # close the connection conn.close
Example version 2
require "bunny" conn = Bunny.new # start a communication session with the AMQP server conn.start # declare a queue q = conn.queue("test1") # declare default direct exchange which is bound to all queues exch = conn.exchange("") # publish a message to the exchange which then gets routed to the queue exch.publish("Hello, everybody!", :key => 'test1') # get message from the queue msg = q.pop_as_hash[:payload] # display the message puts "This is the message: " + msg + "\n\n" # close the connection conn.close
That’s it! Go ahead and try out the preview releases. Hopefully, you’ll find the new improved Bunny helpful in your Ruby RabbitMQ and AMQP work.