Based on the recipe for active objects given in "Concepts, Techniques, and Models of Computer Programming", by Peter van Roy and Seif Haridi, the ActiveObject class wraps an instance of a passive object and forwards messages to this object via a thread-safe message queue. The passive object processes the messages on its own thread, and returns the results to the caller via an AsynchResult object that can be used to block whilst waiting for a result, or to register callbacks to be called when a result is available.
Python, 135 lines
myActiveObject = ActiveObject(MyClass, args, *kwargs) # args and kwargs are passed to the passive object's __init__ function
asyncResult = myActiveObject.doFoo() while not asyncResult.completed: pass # do something else until the result is available print asyncResult.result
myActiveObject.doFoo().result # waits for a result and returns it when available
myActiveObject.doBar().addCallback(callback, errback) # calls callback if the operation succeeded, and errback if it failed.
myActiveObject.stop() # explicitly terminates the message loop used by the active object.
Active objects provide a simple approach to message-passing concurrency, where objects running in separate threads communicate with each other via message queues instead of using shared state with explicit locking to control concurrency.
A Windows form with a main window thread and a message loop may be seen as an example of an active object.
Active objects work better in languages with lightweight threads. Because this implementation assigns a new thread to each active object, it is not efficient to create a large number of objects A more efficient Python implementation would multiplex on a small number of threads in a thread pool, instead of assigning one thread to each active object.
See "Concepts, Techniques, and Models of Computer Programming", by Peter van Roy and Seif Haridi, for an in-depth treatment of active objects, message-passing concurrency and other models used for concurrent programming.