Source code for wbia.web.futures_utils._base_actor

# -*- coding: utf-8 -*-
"""
TODO:
    Actors need to be able to reference each other.
        * this means we need to be able to pass a reference
          that can post a message to an actor's executor.
    Actors need to be able to create more actors.
        * This should be fairly simple if the first task is complete.

    Idea:
        maintain a list of weakreferences to all actor executors ever created
        in a thread. Actors must have a way of interacting with this thread.

"""
from __future__ import absolute_import, division, print_function
from concurrent.futures import _base
import utool as ut

(print, rrr, profile) = ut.inject2(__name__)


[docs]class ActorExecutor(_base.Executor): """ Executor to manage exactly one actor. This class lives in the main thread, manages a process containing exactly one Actor, and is used to send messages to that actor. Responses are returned in the form of a `Future` object. """
[docs] def post(self, message): """ analagous to _base.Executor.submit, but sends a message to the actor controlled by this Executor, and returns a Future. """ raise NotImplementedError('use ProcessActorExecutor or ThreadActorExecutor')
[docs]class Actor(object): """ Base actor class. Actors receive messages, which are arbitrary objects from their managing executor. The main difference is that we expose an `Actor` class which can be inherited from and provides the `executor` classmethod. This creates an asynchronously maintained instance of this class in a separate thread/process Example: >>> # DISABLE_DOCTEST >>> from concurrent.futures import ThreadActor >>> class MyActor(ThreadActor): >>> def __init__(self): >>> self.state = 0 >>> # >>> def handle(self, message): >>> self.state += message >>> return self.state >>> # >>> executor = MyActor.executor() >>> f = executor.post('message') >>> print(f.result()) """
[docs] @classmethod def executor(cls): """ Creates an asychronous instance of this Actor and returns the executor to manage it. """ raise NotImplementedError('use ProcessActor or ThreadActor')
[docs] def handle(self, message): """ This method recieves, handles, and responds to the messages sent from the executor. This function can return arbitrary values. These values can be accessed from the main thread using the Future object returned when the message was posted to this actor by the executor. """ raise NotImplementedError('must implement message handler')