Cottontail
This library is a wrapper around the popular AMQP bunny gem. It is inspired by Sinatra to easily consume messages on different routing keys.
Installation
# Gemfile
gem 'cottontail'Usage: Simple worker
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.startTo 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 &Usage: Worker on multiple queues
# 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
endUsage: Worker that consumes multiple messages and handles them differently
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
endCopyright © Rudolf Schmidt, released under the MIT license