def run_on_empty(self, concurrency): for i in range(0, concurrency): if self.__empty_logic == "broadcast": for provider in self.__providers: asyncio.run_coroutine_threadsafe( self.tell(provider, Pull(None, self))) else: if len(self.__providers) > i: if self.__current_provider >= len(self.__providers): self.__current_provider = 0 prov = self.__providers[self.__current_provider] asyncio.run_coroutine_threadsafe( self.tell(prov, Pull(None, self))) self.__current_provider += 1
async def __do_pull_tick(self, message=None): """ Do a pull tick :param message: The message for the pull tick :type message: Message() """ try: if self.__task_q.full() is False: if self.__providers and len(self.__providers) > 0: for provider in self.__providers: if isinstance(provider, AbstractActor): if provider.get_state() != ActorState.RUNNING: self.__providers.remove(provider) if len(self.__providers) > 0: sender = self.__providers[self.__current_provider] await self.tell(sender,Pull(None, self)) self.__current_provider += 1 if self.__current_provider >= len(self.__providers): self.__current_provider = 0 else: self.__current_provider = 0 else: self.__current_provider = 0 except Exception: self.handle_fail() try: if self.get_state() != ActorState.TERMINATED: self.call_tick() except Exception: self.handle_fail()
async def __signal_provider(self): """ Signal the provider. """ try: prov = self.__providers[self.__current_provider] await self.tell(prov, Pull(None, self)) except Exception as e: self.handle_fail() self.__current_provider += 1 if self.__current_provider >= len(self.__providers): self.__current_provider = 0
def start(self): """ Start the actor """ super().start() if len(self.__providers) > 0: for i in range(0, self.__concurrency): if self.__empty_logic == "broadcast": for provider in self.__providers: self.loop.run_until_complete( self.tell(provider, Pull(None, self))) else: if len(self.__providers) > i: if i < len(self.__providers): lprv = len(self.__providers) if self.__current_provider >= lprv: self.__current_provider = 0 prov = self.__providers[self.__current_provider] self.loop.run_until_complete( self.tell(prov, Pull(None, self))) self.__current_provider += 1
async def __push(self, message): """ Standard push function. :param message: The message to push :type message: Message() """ try: if isinstance(message, Message): sender = message.sender self.on_push(message) if sender: await self.tell(sender, Pull(None, self)) except Exception as e: self.handle_fail()
def __do_pull_tick(self): """ Do a pull tick """ try: if self._task_q.full() is False: sender = self.__providers[self.__current_provider] self.loop.run_until_complete( self.tell(self, Pull(None, sender))) self.__current_provider += 1 if self.__current_provider >= len(self.__providers): self.__current_provider = 0 except Exception as e: self.handle_fail() try: self.loop.call_later(self.tick_delay, self.__do_pull_tick()) except Exception as e: self.handle_fail()
async def pull(self, message): """ The pull message. :param message: The Pull message :type message: Pull() """ try: if isinstance(message, Pull): if self.__task_q.empty(): self.run_on_empty() elif self.__task_q.full() is False: task = self.__task_q.get() if task: await self.tell(self.router, TaskMessage(message)) if self.result_q.empty() is False: sender = message.sender result = self.result_q.get_nowait() self.push_q.put(result) await self.tell(sender, Pull(None, self)) except Exception as e: self.handle_fail()
def start(self): super().start() if len(self.__providers) > 0: for provider in self.__providers: asyncio.run_coroutine_threadsafe( self.tell(provider, Pull(None, self)), self.loop)