Friday, January 29, 2010

Notes on a Message Passing design

I am an avid supporter of "message based" systems. I took the time to perform a quick "brain dump" of some of my thoughts on the subject.



Follows a simple Python based implementation.

"""
Simple "Bus" based message publish/subscribe
Created on 2010-01-28
@author: jldupont
"""
__all__=["Bus"]
class Bus(object):
"""
Simple publish/subscribe "message bus"
with configurable error reporting
Message delivery is "synchronous i.e. the caller of
the "publish" method blocks until all the subscribers
of the message have been "called-back".
Any "callback" can return "True" for stopping the
calling chain.
"""
logger=None
ftable={}
@classmethod
def subscribe(cls, msgType, callback):
"""
Subscribe to a Message Type
@param msgType: string, unique message-type identifier
@param callback: callable instance which will be called upon message delivery
"""
subs=cls.ftable.get(msgType, [])
subs.append(callback)
cls.ftable[msgType]=subs
@classmethod
def publish(cls, msgType, *pa, **kwa):
"""
Publish a message from a specific type on the bus
@param msgType: string, message-type
@param *pa: positional arguments
@param **kwa: keyword based arguments
"""
subs=cls.ftable.get(msgType, [])
for sub_cb in subs:
try:
stop_chain=sub_cb(msgType, *pa, **kwa)
except Exception, e:
stop_chain=True
if cls.logger:
cls.logger(msgType, e)
if stop_chain:
return
## =========================================================== TESTS
if __name__ == '__main__':
class Logger(object):
def __call__(self, msgType, e):
print "Logger: Error: msgType(%s) Exception(%s)" % (msgType, str(e))
def callback(msgType, *pa, **kwa ):
print "cb: msgType(%s) pa(%s) kwa(%s)" % (msgType, pa, kwa)
Bus.logger=Logger()
Bus.subscribe("test", callback)
Bus.subscribe("test", callback)
Bus.publish("test", p1="v1", p2="v2")
Bus.publish("test2", p1="v1", p2="v2")
Bus.subscribe("test", None)
Bus.publish("test", p2="v2", p3="v3")
Bus.logger=None
Bus.publish("test", p2="v2", p3="v3")


I will very likely make other contributions to my blog along the same lines.