Пример #1
0
class Bridge(IActor):
    def __init__(self):
        IActor.__init__(self)
        self.mailbox = Mailbox()

    def send(self, message, sender):
        self.mailbox.send(message, sender)

    def call(self, target, request, timeout, default=None):
        self.send_request(target, request)
        return self.receive_response(timeout, default)

    def multi_call(self, targeted_requests, timeout, default=None):
        count = 0
        for target, request in targeted_requests:
            self.send_request(target, request)
            count += 1

        for _ in xrange(count):
            yield self.receive_response(timeout, default)

    def stop(self, actors, timeout):
        stop = Stop()
        return list(self.multi_call(((actor, stop) for actor in actors), timeout, default=None))

    def send_request(self, target, request):
        target.send(request, self)

    def receive_response(self, timeout, default):
        try:
            message, sender = self.mailbox.receive(timeout=timeout)
            return message
        except Empty:
            return default
Пример #2
0
class Actor(IActor):
    @classmethod
    def spawn(cls, *args, **kwargs):
        self = cls(*args, **kwargs)
        self.mailbox = Mailbox()
        self.start_thread(target=self.act, as_daemon=True)
        return self

    @classmethod
    def start_thread(cls, target, as_daemon, name=None):
        thread = Thread(target=target)
        if name:
            thread.setName(name)
        thread.setDaemon(as_daemon)
        thread.start()
        return thread

    def send(self, message, sender):
        if self.mailbox is None:
            raise ActorNotStartedError()
        else:
            self.mailbox.send(message, sender)

    def receive(self):
        if self.mailbox is None:
            raise ActorNotStartedError()
        else:
            return self.mailbox.receive()

    handles = HandlerRegistry()

    @classmethod
    def make_handles(*classes):
        return HandlerRegistry((typ, handler)
                               for cls in classes
                               for (typ, handler) in cls.handles.iteritems())

    def act(self):
        try:
            while True:
                message, sender = self.receive()
                registry = self.__class__.handles
                handler = registry.get(message.__class__) or registry.get(OtherMessage)
                if handler is not None:
                    handler(self, message, sender)
        except Stop:
            pass

    @handles(OtherMessage)
    def do_other(self, message, sender):
        pass

    @handles(Stop)
    def on_stop(self, message, sender):
        sender.send(Stopped(), self)
        raise message