An eventing gem.
To briefly explain, we want to separate the application/business logic from the framework and runtime. This project is structured so that the application and business rules live in /lib while the framework and runtime components live in /app. events.rb is the bootstrap that kicks off everything.
This is the messaging 'driver.' When the underlying message framework changes, this also must change.
To implement an arbiter, just extend the arbiter class and add a self.publish
method:
class ResqueArbiter < Arbiter
def self.publish(message, metadata)
Resque.enqueue(Arbiter, message, metadata)
end
end
You'll need to specify the classes to listen with on your arbiter driver. For example, if you were using the ResqueArbiter
, you'd do this somewhere in your initialization of your application:
ResqueArbiter.set_listeners([Classes, To, Listen, On])
This is the application-side eventing component. It is a singleton or statically invoked throughout the app and understands how to talk to the arbiter. In your application, you need to add an arbiter to the Eventer bus:
Eventer.bus = ResqueArbiter
It publish an event, use the Eventer.post
method. It takes two arguments:
- The event name
- A hash of arguments to pass
For example
Eventer.post(:account_created, account.to_hash)
Just a side note, it's not advised to push symbols into events, as they likely won't be received as symbols on the other side.
To create a class that listens on an event, it must conform to some conventions:
- have a
@subscribe_to
array - have a
notify(event, args)
method
The @subscribe_to
array tells the arbiter which events you want this class to listen for
The notify
method should inspect the event
that comes in, and act accordingly. For example:
class Postmaster
@subscribe_to = [:hello]
class << self
attr_accessor :router
attr_accessor :record
attr_reader :subscribe_to
end
def self.send_hello(recipient_id)
# Send some email here
end
def self.notify(event, args)
case event
when :hello
send_hello(*args)
end
end
end
These are the provided arbiter drivers:
The in-memory arbiter is the default, simplest driver. This is an in-memory arbiter, and is only really useful for testing. If you use this in production, it will handle events in-process, which probably isn't what you want.
This is an Arbiter implementation that uses a Resque backend. You'll need a Resque worker running to process events. See the resque manual for details on this.
This is an Arbiter that uses ZeroMQ and the Majordomo Protocol to send it's messages. It submits asynchronously to dispatch work via a broker (which is not provided by this gem). You must also have majordomo workers receiving and processing the work (workers are also not provided).
You'll need to setup some configuration in your app to use this arbiter.
- Address: The address of the Majordomo broker
- ZMQ Context: the ZMQ context implementation
- Timeout: timeout in seconds
- MD Service: The service name to use with Majordomo. This is how messages are routed.
Example:
require 'arbiter'
require 'ffi-rzmq'
class ZeromqConfig
arbiter = Zeromq::Majordomo::AsynchronousArbiter.new(
"tcp://192.168.1.1:9292",
ZMQ::Context.new,
5,
"some-service-name-v1"
)
end