def __init__(self, actor_ref, attr_path=None): if not actor_ref.is_alive(): raise ActorDeadError('%s not found' % actor_ref) self.actor_ref = actor_ref self._actor = actor_ref._actor self._attr_path = attr_path or tuple() self._known_attrs = self._get_attributes() self._actor_proxies = {} self._callable_proxies = {}
def _actor_loop(self): """ The actor's event loop. This is the method that will be executed by the thread or greenlet. """ try: self.on_start() except Exception: self._handle_failure(*sys.exc_info()) while not self.actor_stopped.is_set(): message = self.actor_inbox.get() reply_to = None try: reply_to = message.pop('pykka_reply_to', None) response = self._handle_receive(message) if reply_to: reply_to.set(response) except Exception: if reply_to: logger.debug('Exception returned from %s to caller:' % self, exc_info=sys.exc_info()) reply_to.set_exception() else: self._handle_failure(*sys.exc_info()) try: self.on_failure(*sys.exc_info()) except Exception: self._handle_failure(*sys.exc_info()) except BaseException: exception_value = sys.exc_info()[1] logger.debug('%s in %s. Stopping all actors.' % (repr(exception_value), self)) self._stop() ActorRegistry.stop_all() while not self.actor_inbox.empty(): msg = self.actor_inbox.get() reply_to = msg.pop('pykka_reply_to', None) if reply_to: if msg.get('command') == 'pykka_stop': reply_to.set(None) else: reply_to.set_exception( ActorDeadError( '%s stopped before handling the message' % self.actor_ref))
def tell(self, message): """ Send message to actor without waiting for any response. Will generally not block, but if the underlying queue is full it will block until a free slot is available. :param message: message to send :type message: picklable dict :raise: :exc:`pykka.ActorDeadError` if actor is not available :return: nothing """ if not self.is_alive(): raise ActorDeadError('%s not found' % self) self.actor_inbox.put(message)