Routing and handlers
Handlers
A handler is a piece of code that does something with a message. There is no module or superclass that you need to use to implement a handler. All that is needed is something that responds to .call with one argument, the message.
The following class can serve as a typical handler:
class NotifyCompetingBidders
def self.call(bid_placed)
other_bidders.each { |bidder| SendOutbidNotice.call(recipient: bidder) }
end
end
But a handler can also be a plain block in a route:
class HandleBiddingEvents
include Messaging::Routing
def self.call(message)
new.handle(message)
end
# A block used as a handler
on BidPlaced do |bid_placed|
log_bid_event bid_placed
end
end
Routing
There are multiple ways to route messages to handlers.
Synchronous handlers
Use the call: keyword in a route to make the handler synchronous.
Messaging.routes.draw do
on Events::BidPlaced, call: NotifyCompetingBidders
end
Be aware! The handler would trigger in the same thread as the code that publishes the event. This may or may not be a problem. But think twice before using synchronous handlers.
Enqueued handlers
Use the enqueue: keyword to make a handler be called by a background worker like Sidekiq.
Messaging.routes.draw do
on Events::BidPlaced, enqueue: NotifyCompetingBidders
end
Be aware! Sidekiq / Resque / ActiveJob does not guarantee that the jobs will be processed in any specific order. If the order in which handlers gets called is important you should probably use a Consumer instead