class EndpointWriterMailbox(AbstractMailbox): def __init__(self, batch_size): self._batch_size = batch_size self._system_messages = UnboundedMailboxQueue() self._user_messages = UnboundedMailboxQueue() self._dispatcher = None self._invoker = None self._event = threading.Event() self._suspended = False def post_user_message(self, msg): self._user_messages.push(msg) self.__schedule() def post_system_message(self, msg): self._system_messages.push(msg) self.__schedule() def register_handlers(self, invoker, dispatcher): self._invoker = invoker self._dispatcher = dispatcher self._dispatcher.schedule(self.__run) def start(self): pass async def __run(self): while True: self._event.wait() await self.__process_messages() self._event.clear() if self._system_messages.has_messages() or self._user_messages.has_messages(): self.__schedule() def __schedule(self): self._event.set() async def __process_messages(self): message = None try: batch = [] sys = self._system_messages.pop() if sys is not None: if isinstance(sys, SuspendMailbox): self._suspended = True elif isinstance(sys, ResumeMailbox): self._suspended = False else: message = sys await self._invoker.invoke_system_message(sys) if not self._suspended: batch.clear() while True: msg = self._user_messages.pop() if msg is not None or self._batch_size <= len(batch): batch.append(msg) else: break if len(batch) > 0: message = batch await self._invoker.invoke_user_message(batch) except Exception as e: await self._invoker.escalate_failure(e, message)
class EndpointWriterMailbox(AbstractMailbox): def __init__(self, batch_size): self._batch_size = batch_size self._system_messages = UnboundedMailboxQueue() self._user_messages = UnboundedMailboxQueue() self._suspended = False self._dispatcher = None self._invoker = None self._event = threading.Event() self._async_event = None self._loop = None self._logger = log.create_logger(logging.INFO, context=EndpointWriterMailbox) def post_user_message(self, msg): self._user_messages.push(msg) self.__schedule() def post_system_message(self, msg): self._system_messages.push(msg) self.__schedule() def register_handlers(self, invoker, dispatcher): self._invoker = invoker self._dispatcher = dispatcher self._dispatcher.schedule(self.__run) self._event.wait() def start(self): pass def __initialize(self): self._loop = asyncio.get_event_loop() self._async_event = asyncio.Event() self._event.set() async def __run(self): self.__initialize() while True: await self._async_event.wait() await self.__process_messages() self._async_event.clear() if self._system_messages.has_messages( ) or self._user_messages.has_messages(): self.__schedule() async def __process_messages(self): message = None try: batch = [] if sys := self._system_messages.pop(): if isinstance(sys, SuspendMailbox): self._suspended = True elif isinstance(sys, ResumeMailbox): self._suspended = False else: message = sys await self._invoker.invoke_system_message(sys) if not self._suspended: batch.clear() while msg := self._user_messages.pop(): batch.append(msg) if len(batch) >= self._batch_size: break if len(batch) > 0: message = batch await self._invoker.invoke_user_message(batch)