MessageCenter(message router) using concurrence module
<p>concurrence is a framework for concurrent networking in python. For more detail infromation, visit that site.(<a href="http://opensource.hyves.org/concurrence/" rel="nofollow">http://opensource.hyves.org/concurrence/</a>) This framework supports a unit of task called Tasklet. This unit is able to send message each other.</p>

<p>I made the code to help persons who use the framework. It helps them to control Tasklet's message. The following code is a message router which routes any message from any Tasklet's message to registered Tasklet. It seems like the <a href="https://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/Notifications/Introduction/introNotifications.html#//apple_ref/doc/uid/10000043i" rel="nofollow">Notification Center concept</a> in Cocoa. </p>

<p>If you find some bug or weak point on the code. Please fix it and make it better. :-)</p>

<p><strong>msgcenter.py</strong>  </p>

<pre><code>from concurrence import Tasklet, Message, dispatch

class MCMessage(object):
    def __init__(self, msg, receiver):
        # a class derived from concurrence.Message
        self.msg = msg
        # tasklet
        self.sender = Tasklet.current()
        # tasklet
        self.receiver = receiver
        # user-defined data to be passed to receiver tasklet
        self.userinfo = None

    def payload(self, userinfo):
        self.userinfo = userinfo

class MsgCenter(object):
    #   CONSTANTS
    #   don't change that values
    TASK = 0
    MSG = 1

    def __init__(self):
        self._msgs = []
        # Run router tasklet
        self._receiver = Tasklet.new(self._msg_loop)()

    #   Register any receiver tasklet and message derived from concurrence.Message
    #   task:   receiver tasklet
    #   msg:    message derived from concurrence.Message.
    def register(self, task, msg):
        self._msgs.append((task, msg))

    #   Send the message to receiver tasklet
    #   arg:    message that is an instance of MCMessage.
    #   task:   receiving tasklet
    def send(self, arg, task = None):
            arg.msg.send(self._receiver)(arg)

    def _msg_loop(self):
        for msg, args, kwargs in Tasklet.receive():
            for m in self._msgs:
                if msg.match(m[1]):
                    self._send_msg(m, args[0])

    def _send_msg(self, target, msg):
        if msg.receiver != None and msg.receiver != target[self.TASK]:
            return

        target[self.MSG].send(target[self.TASK])(msg)

if __name__ == "__main__":
    print "use test_msgcenter.py"
</code></pre>

<p><strong>test_msgcenter.py</strong>  </p>

<pre><code>from concurrence import Tasklet, Message, dispatch, TimeoutError
from msgcenter import MCMessage, MsgCenter

g_msg_center = MsgCenter()

class MSG_GREETING(Message):
    name = "MSG_GREETING"

class MSG_FAREWELL(Message):
    name = "MSG_FAREWELL"

def printer1():
    g_msg_center.register(Tasklet.current(), MSG_GREETING)
    g_msg_center.register(Tasklet.current(), MSG_FAREWELL)

    for msg, args, kwargs in Tasklet.receive():
        if msg.match(MSG_GREETING):
            print 'printer1 Hello', args[0].userinfo
        elif msg.match(MSG_FAREWELL):
            print 'printer1 Goodbye', args[0].userinfo
        else:
            pass

def printer2():
    g_msg_center.register(Tasklet.current(), MSG_GREETING)
    g_msg_center.register(Tasklet.current(), MSG_FAREWELL)

    while True:
        try:
            for msg, args, kwargs in Tasklet.receive(1):
                if msg.match(MSG_GREETING):
                    print 'printer2 Hello', args[0].userinfo
                elif msg.match(MSG_FAREWELL):
                    print 'printer2 Goodbye', args[0].userinfo
                else:
                    pass
        except TimeoutError, e:
            pass
        print "do another job.."


def sender1():
    print "task(%s) sleep 5 sec..." % (Tasklet.current().name)
    Tasklet.sleep(5)

    mcitem = MCMessage(MSG_FAREWELL, None)
    mcitem.payload("everybody")
    print "send task(%s) msg(%s) to ALL" % (Tasklet.current().name, MSG_FAREWELL.name)
    g_msg_center.send(mcitem)
    print "continue..."

def main():
    global g_msg_center

    printer1_task = Tasklet.new(printer1)()
    printer2_task = Tasklet.new(printer2)()
    sender1_task = Tasklet.new(sender1)()

    Tasklet.sleep(0)

    mcitem1 = MCMessage(MSG_GREETING, printer1_task)
    mcitem1.payload("kyokook")
    print "send task(%s) msg(%s) to task(%s)" % (Tasklet.current().name, MSG_GREETING.name, printer1_task.name)
    g_msg_center.send(mcitem1)

    mcitem2 = MCMessage(MSG_FAREWELL, printer2_task)
    mcitem2.payload("fullc0de")
    print "send task(%s) msg(%s) to task(%s)" % (Tasklet.current().name, MSG_FAREWELL.name, printer2_task.name)
    g_msg_center.send(mcitem2)


dispatch(main)
</code></pre>

<p>I hope that it is useful code for anyone.</p>
