!!! NO LONGER MAINTANED !!!
RenoFi moved to Google Pub/Sub and doesn't use rabbitmmq/jackhammer anymore.
jackhammer
jackhammer
is an opinionated, configurable facade over the RabbitMQ Bunny
module.
Installation
Add this line to your application's Gemfile:
gem 'jackhammer'
And then execute:
$ bundle
Or install it yourself as:
$ gem install jackhammer
Usage
Quick Start
Create a YAML file to configure topics and queues your Jackhammer::Server instance will subscribe to when using the executable.
# config/jackhammer.yml
---
default: &default
weather:
auto_delete: false
durable: true
queues:
# queue_name => options pairs
americas.south:
auto_delete: true
durable: false
exclusive: false
handler: "MyApp::SouthAmericaHandler"
routing_key: "americas.south.#"
americas.north:
auto_delete: true
durable: false
exclusive: false
handler: "MyApp::NorthAmericaHandler"
routing_key: "americas.north.#"
# or an array
- queue_name: americas.south
auto_delete: true
durable: false
exclusive: false
handler: "MyApp::SouthAmericaHandler"
routing_key: "americas.south.#"
# queue_name can be skipped and auto generated from routing key
- auto_delete: true
durable: false
exclusive: false
handler: "MyApp::SouthAmericaHandler"
routing_key: "americas.south.#"
development:
<<: *default
test:
<<: *default
production:
<<: *default
Configure your subscription server by sublcassing Jackhammer::Server
.
# config/environment.rb
require 'jackhammer'
module MyApp
class Server < Jackhammer::Server
configure do |config|
# these are the default options
config.connection_options = {}
config.connection_url = nil
config.environment = ENV['RACK_ENV'] || :development
config.exception_adapter = proc { |e| raise e }
config.logger = Logger.new(IO::NULL)
config.publish_options = { mandatory: true, persistent: true }
config.yaml_config = "config/jackhammer.yml"
config.app_name = "my_app"
config.client_middleware.use MyClientMiddleware, some_arg: 1, other_arg: 2
config.server_middleware.use MyServerMiddleware
end
end
end
Start the subscription server to read the YAML and subscribe to topic queues.
$ bundle exec jackhammer
Topic Exchange Configuration
The YAML file configures RabbitMQ Topic Exchanges.
At the root are environment names used to load environment specific
configuration. Below that are the names of topic exchanges. Each topic exchange
can define durable
and auto_delete
options used when creating the exchange.
Additionally, each topic exchange defines a queues
mapping. Each mapping
nested under the queues
key represents options used by either Jackhammer or
Bunny.
Exchange topic queue options passed to Bunny during queue initialization:
- durable default: false — Should this queue be durable?
- auto_delete default: false — Should this queue be automatically deleted when the last consumer disconnects?
- exclusive default: false — Should this queue be exclusive (only can be used by this connection, removed when the connection is closed)?
The routing_key is used as an option when binding the Bunny::Queue and Bunny::Exchange.
Exchange topic queue options used by Jackhammer:
- handler A string representing the name of a class that is intended to receive messages delivered to the queue subscriber.
The handler class must implement at least a .call
method. If the class
responds to .perform_async
then that will be called instead of .call
.
module MyApp
class SouthAmericaHandler
def self.call(message)
puts message
end
end
end
Executable
By default the executable will load config/environment.rb
. If you define
and configure your Jackhammer server somewhere else, use the -r path/file.rb
option on the command line.
$ bundle exec jackhammer -r config/rabbitmq_application.rb
Server Configuration
The configure
block must be placed inside of your application class even if
you choose not to change any default configuration.
The intent of the options might not be obvious by looking at the name.
-
connection_options passed into
Bunny.new
. -
connection_url passed into
Bunny.new
. - environment specifies the section of YAML config to load.
-
exception_adapter exceptions caught when handling received messages are
forwarded to the adapter object. The adapter must implement
.call(exception)
. - logger defines a logger the Jackhammer module should use.
- publish_options defines options passed to all messages published (can be overridden by passing the same options as arguments in your code).
- yaml_config defines the file location of the Topic Exchange YAML configuration file.
- client_middleware defines hooks that will be executed prior to publishing a message to a topic
- server_middleware defines hooks that will be executed prior to running the message handler
You can find defaults specified in the Jackhammer::Configuration class constructor.
Middleware
Middleware allows you to hook into message publishing (client) and handling (server).
It can be used to transform the passed in arguments before passing them along or to halt the execution completely. The execution will be halted if the middleware instance does not yield.
Example client middleware
class MyClientMiddleware
def initialize(name)
@name = name
end
def call(message, options)
options[:headers][:hello] = @name
yield message, options
end
end
Example server middleware
class MyServerMiddleware
def call(handler:, delivery_info:, properties:, content:)
puts "Hello, #{properties[:headers]['name']}!"
yield handler: handler, delivery_info: delivery_info, properties: properties, content: content
end
end
Development
After checking out the repo, run bin/setup
to install dependencies. Then, run rake spec
to run the tests. You can also run bin/console
for an interactive prompt that will allow you to experiment.
To install this gem onto your local machine, run bundle exec rake install
. To release a new version, update the version number in version.rb
, and then run bundle exec rake release
, which will create a git tag for the version, push git commits and tags, and push the .gem
file to rubygems.org.
Contributing
Bug reports and pull requests are welcome on GitHub at https://github.com/renofi/jackhammer. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the Contributor Covenant code of conduct.
License
The gem is available as open source under the terms of the MIT License.