Beispiel #1
0
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)
Beispiel #2
0
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)