Jean-Lou Dupont developed a Python implementation of the actor model design pattern called mswitch that facilitates message passing between loosely coupled actors. mswitch acts as an anonymous message bus that connects actors, allowing first-time messages to be broadcast to all interested actors and subsequent messages to only be delivered to explicitly interested actors. Actors connect to mswitch and can send and receive messages, with mswitch handling the routing. This implementation supports both inter-process and intra-process communication between distributed actors.
2. me
● President of Data-Tester Inc.
○ Fiber Optics Test Equipment company
○ Build system / Python
○ Web-Services on Google AppEngine / Python
● Python since ~2007
3. what
● Actor Design Pattern
○ concurrency
○ abstraction
○ based on "message passing"
● "mswitch": an implementation in Python
4. why
● Facilitates the "Actor Design Pattern"
○ Less "boiler plate" code
■ No per message type "wiring"
○ Increased flexibility (loose coupling)
5. mswitch / attributes
● Software based Message Bus (mswitch)
○ Anonymous Sender
○ Receiver based "wiring"
○ Snooping support (for debugging)
● Can either be
○ inter-process
○ intra-process
6. how
● Actors are "adresseless"
● Each Actor "connects" to the mswitch
● First time a message of a Type X is sent
○ All Actors receive the message
○ Each Actor signals "interest" for a message Type X
● On subsequent message message of Type X
○ only the Actor(s) which explicitly expressed their
interest receive the message
9. architecture / sending
Actor Actor Actor
1 2 3
Message Switch
● Actor sends message of Type X for 1st time
○ All other Actors receive it
● Split Horizon
○ Sender doesn't receive what it sends
10. architecture / wiring
Actor Actor Actor
1 2 3
Message Switch
● Each Actor wires itself for message Type X
○ Actor replies "Interested" --> mswitch places "wire"
○ Actor replies "! Interested" --> mswitch removes "wire"
11. Example /1
Web
Presenter Cache Fetcher
data? data?
mswitch
data? snooping
Manager Stats
● Actor "Manager" wants to have some "data"
● Actor "Stats" maintains various statistics about the system
12. Example /2
Web
Presenter Cache Fetcher
data data data
(none) (none) (none)
mswitch
data
(none)
snooping
Manager Stats
● Actor "Cache" doesn't have a fresh copy of "data"
● Actor "Fetcher" understands to go fetch the data from the remote source
● Actors "Manager" and "Presenter" understand they have to wait for the data
13. Example /3
Web
Presenter Cache Fetcher
data data data
mswitch
data
snooping
Manager Stats
● Actor "Fetcher" provides a fresh copy of "data"
● Actor "Cache" caches "data"
● Actors "Manager" and "Presenter" receive the required "data"
14. code /1
""" mswitch module """
from Queue import Queue, Empty
def publish(orig, msgType, *pargs, **kargs):
q=_switch.iq
if msgType.startswith("__"):
q=_switch.isq
q.put((orig, msgType, (pargs, kargs)), block=False)
def subscribe(orig, q, sq):
_switch.iq.put((orig, "__sub__", (q, sq)), block=False)
Normal priority queue: iq
High priority queue: isq
15. code /2
""" Actor base """
class ActorThreadedBase(Thread, ActorBase):
def __init__(self):
Thread.__init__(self)
ActorBase.__init__(self)
def run(self):
"""message loop"""
mswitch.subscribe(self.id, self.iq, self.isq)
_quit=False
while not _quit:
_quit=process_queues(self)
Details omitted
16. code /3
""" Example Actor """
class ActorExample(ActorThreadedBase):
def __init__(self):
ActorThreadedBase.__init__(self)
def hq_data(self, msg):
""" handler for the 'data?' message """
def h_data(self, msg):
""" handler for the 'data' message """
_=ActorExample()
_.start()
17. final word
● Bunch of open-source projects based on this
technique ( see http://www.systemical.com )
● Don't hesitate to get in touch:
mailto:jldupont@systemical.com
jeanlou.dupont@gmail.com