PARLEY

Python Actor Runtime LibrarY*

* (the "E" is for Erlang)

[ Introduction | Usage | Documentation | Bugs | Download ]

Introduction

PARLEY is an API for writing Python programs that implement the Actor model of distributed systems, in which lightweight concurrent processes communicate through asynchronous message-passing. Actor systems typically are easier to write and debug than traditional concurrent programs that use locks and shared memory.

PARLEY can run using either traditional native threads, greenlets (lightweight threads), or Stackless Python's tasklets. A program written using PARLEY can choose between these models by changing a single line of code.

Usage

Messages in PARLEY can be arbitrary objects, but the standard message format is a 4-tuple: (tag, sender, args, kwargs). A typical way to handle such a message is to look up a function based on the tag; pass args and kwargs as parameters to the function (args being position parameters, and kwargs being keyword parameters); and to send the return value of the function as a message to the original sender.

Here is a basic server that accepts two values and returns their sum:

from parley import *

def adder():
    while True:
        msg, sender, args, kwargs = recv()
        if msg == 'quit':
            break
        elif msg == 'add':
            ret = args[0] + args[1]
            sender.send('reply', me(), ret)

The module parley.helpers contains a number of classes and function decorators that simplify writing typical "server" actors. The above function could instead be written as:

from parley.helpers import function_actor

@function_actor
def adder2(op1, op2):
    return op1 + op2

And here is a complete program that spawns the adder actor, send it ten requests, and then stops.

from parley import *

def main():
    # a is an actor proxy object that can be used to communicate with
    # the spawned actor.
    a = spawn_link(adder2)
    for i in range(10):
        # This method call is equivalent to the following:
        # a.send('add', me(), i, i+2)
        print a.add(i, i+2)

if __name__=='__main__':
    start_thread_controller(main)

To use greenlets instead of threads, simply change start_thread_controller to start_greenlet_controller.

Greenlets and tasklets have very low overhead compared to threads; using these execution models, it should be possible to start arbitrarily many actors without a significant performance penalty.

Documentation

PARLEY version 0.3 contains other features not described above, such as:
- the ability to register an actor at a global name.
- linking actors together to be alerted about normal and abnormal termination of linked actors.
- the ability to record sent messages to a file or to stdout.

Full API documentation, automatically extracted from the source code, is available. In particular, the following modules are relevant to PARLEY users:

- parley
- parley.helpers
- parley.proxy

One can also see the documentation by running the following at the interactive Python console:

>>> import parley, parley.proxy, parley.helpers
>>> help(parley)
>>> help(parley.proxy.ActorProxy)
>>> help(parley.helpers)

Known Bugs / Limitations

PARLEY is still beta. Some parts have been tested less than others; expect to find bugs.

The threaded execution model should work on all version of Python that support threads. The tasklet execution model should work with Stackless Python and PyPy; it has been tested under stackless 2.4 and PyPy 1.0 (on Linux). The greenlet execution model works with any version of Python, as long as the py library is installed.

Many discrepancies still remain between the thread execution model and the tasklet/greenlet models. Most notably, tasklets cannot make blocking function calls without suspending the entire program. Blocking calls (such as sleeping and I/O) must therefore be performed either asynchronously or in a separate thread.

To move in this direction, PARLEY version 0.4 will build on the greenlet execution model to create a hybrid model that supports both threads and greenlets. Future versions may then use thread pools or asynchronous wrappers to enable transparent use of standard I/O routines.

The ID of an actor is currently local to its controller. A future version will test whether an actor is local or remote and forward messages appropriately. Being able to network-enable PARLEY may depend on resolving the problem of blocking calls described above.

Download

Version 0.3 (07/22/2007): parley-0.3.tar.gz
New greenlet controller, plus some more features, bugfixes, and tests; see the ChangeLog for details. The greenlet controller is now the recommended platform: it does not require Stackless python, and it will be the basis for future I/O-related work.
Version 0.2 (05/09/2007): parley-0.2.tar.gz
Bugfixes, better documentation, and some new features; see the ChangeLog for details.
Version 0.1.1 (04/28/2007): parley-0.1.1.tar.gz
Now packaged using distutils.
Version 0.1 (04/26/2007): parley-0.1.tar.gz

PARLEY is licensed under the GNU Lesser General Public License (LGPL). Essentially, one can use the library in both free and proprietary applications, but any modifications made to the library itself must be made available under the LGPL.

You can check out the latest version from Subversion using the following command:

svn co http://artdent.homelinux.net/parley/trunk

It is also possible to browse the repository online.


Contact: Jacob Lee