Skip to main content

A minimalist actor framework in Python.

Project description

A minimalist actor framework in Python.

  • Free software: MIT license

Installation

pip install pactor

Running the Example

Clone the repo locally, then run the following commands:

pipenv install
pipenv run python -m pactor

To exit, press q.

Documentation

The actor model is a computational model that is useful for concurrent execution. See: https://en.wikipedia.org/wiki/Actor_model.

pactor is a minimalist implementation of the actor model in Python, using multiprocessing.

The actor model stipulates that actors only interact with each other through messaging. pactor implements that restriction by building a proxy around an actor class and converting method calls into messages.

To wrap a pickleable class as an Actor, simply create an Actor with an instance of the target class, as follows:

class MyActor:
    def __init__(self, name):
        self.name = name

    def some_method(self):
        ...

actor_instance = Actor(MyActor())
The Actor class provides a couple of key capabilities:
.proxy
A proxy object that has methods that mirror those on the wrapped class. Calling a method on the proxy will generate a message to the actor process with the provided parameters.

.close()
Signals that the actor process should discontinue processing messages and terminate.

.join()
Blocks the calling thread until the actor process terminates.

Additionally, the actor class itself is enhanced with an enqueue method that can be used to send messages to itself.

Consider this simple example of a Monitor:

class Monitor:
    def __init__(self, name, aggregator):
        self.name = name
        self.aggregator = aggregator
        self.status = 0

    def read_status(self):
        self.status = fetch_status()
        self.aggregator.update_status(self.name, self.status)
        self.enqueue(self.read_status) # queue up another read

And an Aggregator:

class Aggregator:
    def update_status(self, target_name, status):
        print('Status update for %s: %s' % (target_name, status))

These could be used as follows:

def main():
    aggregator = Actor(Aggregator('aggregator'))
    primary_mon = Actor(Monitor('primary', aggregator.proxy))
    secondary_mon = Actor(Monitor('secondary', aggregator.proxy))

    primary_mon.read_status()
    secondary_mon.read_status()

    aggregator.join()

This simple example highlights several critical points:

  • Each Actor class will actually run in a separate process
  • One Actor can be passed to another Actor using the .proxy member
  • Invoking a method on an Actor proxy does not directly invoke that method on the calling thread, but instead is wrapped as a message and passed to the actor process.

Development

To run the all tests run:

tox

Changelog

0.0.1 (2019-12-10)

  • First release on PyPI.

Project details


Release history Release notifications

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Files for pactor, version 0.1.0
Filename, size File type Python version Upload date Hashes
Filename, size pactor-0.1.0-py2.py3-none-any.whl (7.7 kB) File type Wheel Python version py2.py3 Upload date Hashes View hashes
Filename, size pactor-0.1.0.tar.gz (15.7 kB) File type Source Python version None Upload date Hashes View hashes

Supported by

Elastic Elastic Search Pingdom Pingdom Monitoring Google Google BigQuery Sentry Sentry Error logging AWS AWS Cloud computing DataDog DataDog Monitoring Fastly Fastly CDN DigiCert DigiCert EV certificate StatusPage StatusPage Status page