Skip to content

Instantly share code, notes, and snippets.

@eyston
Created Jun 19, 2011
Embed
What would you like to do?
Message Bus Blog Example
module MessageBus
class MessageBus
@handlers = {}
def self.subscribe message, handler, method
@handlers[message] ||= []
@handlers[message] << { :handler => handler, :method => method }
end
def self.send message, args
raise "There are no handlers for #{message}" unless @handlers.include? message
raise "There is more than one handler for #{message}" if @handlers[message].size > 1
handler = @handlers[message].first
handler[:handler].send handler[:method], args
end
def self.publish message, args
@handlers[message] ||= []
@handlers[message].each do |handler|
handler[:handler].send handler[:method], args
end
end
end
module MessageHandler
def handles message, method = message
MessageBus.subscribe message, self, method
end
def subscribes message, method = message
handles message, method
end
end
module EventHandler
include MessageHandler
end
module CommandHandler
include MessageHandler
end
def self.send message, args
MessageBus.send message, args
end
def self.publish message, args
MessageBus.publish message, args
end
end
class UpdateCustomerName
extend MessageBus::CommandHandler
handles :update_customer_name, :handle # override default method for command
def self.handle args
id = args.fetch(:id)
name = args.fetch(:name)
customer = Customer.find(id)
customer.update_name name
Customer.save(customer)
end
end
class Customer
@customers = {}
def self.find id
# some fake persistence ...
customer = @customers[id] ||= Customer.new(id)
end
def self.save customer
@customers[customer.id] = customer
end
attr_accessor :id, :name
def initialize id, name = ""
@id = id
@name = name
end
def update_name name
@name = name
MessageBus.publish :customer_name_updated, { :id => @id, :name => @name }
end
end
class Logger
extend MessageBus::EventHandler
subscribes :customer_name_updated
def self.customer_name_updated args
id = args.fetch(:id)
name = args.fetch(:name)
puts "Customer #{id} changed their name to #{name}"
end
end
MessageBus.send :update_customer_name, {:id => 1, :name => "Acme LLC" }
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment