This library is a wrapper around the popular AMQP bunny gem. It is inspired by Sinatra to easily consume messages on different routing keys.
# Gemfile
gem 'cottontail'
When using this gem, you should already be familiar with RabbitMQ and, ideally, the Bunny gem as it is used internally. Given we place our code into worker.rb
, we can define a simple class like so:
# worker.rb
require 'cottontail'
class Worker
include Cottontail::Consumer
session ENV['RABBITMQ_URL'] do |worker, bunny|
channel = bunny.create_channel
queue = channel.queue('', durable: true)
worker.subscribe(queue, exclusive: true, ack: false)
end
consume do |delivery_info, properties, payload|
logger.info payload.inspect
end
end
# The following will start Cottontail right away. You need to be aware that it
# will enter a subscribe loop, so it will block the process. If you don't want
# that, you can start it non-blocking with `Worker.start(false)`.
Worker.start
To run it, you may start it like the following code example. However, you should use a more sophisticated solution for daemonizing your processes in a production environment. See http://www.ruby-toolbox.com/categories/daemonizing for futher inspiration.
ruby worker.rb &
# worker.rb
require 'cottontail'
class Worker
include Cottontail::Consumer
session ENV['RABBITMQ_URL'] do |worker, bunny|
channel = bunny.create_channel
queue_a = channel.queue('queue_a', durable: true)
worker.subscribe(queue_a, exclusive: true, ack: false)
queue_b = channel.queue('queue_b', durable: true)
worker.subscribe(queue_b, exclusive: true, ack: false)
end
consume do |delivery_info, properties, payload|
logger.info payload.inspect
end
end
You are able to scope consume
blocks. Like this, you can make a worker class
a lot easier to read. The following options are available: :exchange
, :queue
and :route
.
If your worker is subscribed to messages, but has no default consume
block
defined, cottontail's logger will write a error message. However, you can always
include a fallback without any parameters.
# worker.rb
require 'cottontail'
class Worker
include Cottontail::Consumer
session ENV['RABBITMQ_URL'] do |worker, bunny|
channel = bunny.create_channel
# Creates the `topic` exchange 'cottontail-exchange', binds the
# queue 'cottontail-queue' to it and listens to any possible
# routing key ('#').
exchange = channel.topic('cottontail-exchange')
queue = channel.queue('cottontail-queue', durable: true)
.bind(exchange, routing_key: '#')
worker.subscribe(queue, exclusive: true, ack: false)
end
# This handles any message with the routing key 'message.sent'
consume route: 'message.sent' do |delivery_info, properties, payload|
logger.info 'Received via routing key `message.sent`'
end
# This handles any message with the routing key 'message.read'. Also,
# it uses the short notation (without the hash syntax).
consume 'message.read' do |delivery_info, properties, payload|
logger.info 'Received via routing key `message.read`'
end
# In case no other consume block matches the criteria, this fill be
# the fallback to any message coming in.
consume do |delivery_info, properties, payload|
logger.info 'Anything else goes here'
end
end
Copyright © Rudolf Schmidt, released under the MIT license