Exemple #1
0
    def dispatch(self, connection, message, connection_id):
        if message.message_type in self._msg_type_handlers:
            priority = self._priority.get(message.message_type, Priority.LOW)
            message_id = _gen_message_id()
            LOGGER.info("Received a message of type %s priority %d from %s",
                        get_enum_name(message.message_type), priority,
                        connection_id)
            self._message_information[message_id] = \
                _MessageInformation(
                    connection=connection,
                    connection_id=connection_id,
                    content=message.content,
                    correlation_id=message.correlation_id,
                    message_type=message.message_type,
                    collection=_ManagerCollection(
                        self._msg_type_handlers[message.message_type]))

            self._in_queue.put_nowait((priority, message_id))

            queue_size = self._in_queue.qsize()
            LOGGER.info("Queue size %s", queue_size)
            if queue_size > 10:
                LOGGER.debug("Dispatch incoming queue size: %s", queue_size)
        else:
            LOGGER.info(
                "received a message of type %s "
                "from %s but have no handler for that type",
                get_enum_name(message.message_type), connection_id)
Exemple #2
0
    def _determine_next(self, message_id, future):
        if future.result().status == HandlerStatus.DROP:
            del self._message_information[message_id]

        elif future.result().status == HandlerStatus.PASS:
            self._process(message_id)

        elif future.result().status == HandlerStatus.RETURN_AND_PASS:
            connection, connection_id, \
                original_message, _ = self._message_information[message_id]

            message = validator_pb2.Message(
                content=future.result().message_out.SerializeToString(),
                correlation_id=original_message.correlation_id,
                message_type=future.result().message_type)
            try:
                self._send_message[connection](msg=message,
                                               connection_id=connection_id)
            except KeyError:
                LOGGER.info(
                    "Can't send message %s back to "
                    "%s because connection %s not in dispatcher",
                    get_enum_name(message.message_type), connection_id,
                    connection)
            self._process(message_id)

        elif future.result().status == HandlerStatus.RETURN:
            connection, connection_id,  \
                original_message, _ = self._message_information[message_id]

            del self._message_information[message_id]

            message = validator_pb2.Message(
                content=future.result().message_out.SerializeToString(),
                correlation_id=original_message.correlation_id,
                message_type=future.result().message_type)
            try:
                self._send_message[connection](msg=message,
                                               connection_id=connection_id)
            except KeyError:
                LOGGER.info(
                    "Can't send message %s back to "
                    "%s because connection %s not in dispatcher",
                    get_enum_name(message.message_type), connection_id,
                    connection)
        with self._condition:
            if len(self._message_information) == 0:
                self._condition.notify()
Exemple #3
0
    def broadcast(self, gossip_message, message_type, exclude=None):
        """Broadcast gossip messages.

        Broadcast the message to all peers unless they are in the excluded
        list.

        Args:
            gossip_message: The message to be broadcast.
            message_type: Type of the message.
            exclude: A list of connection_ids that should be excluded from this
                broadcast.
        """
        LOGGER.debug("broadcast...")
        with self._lock:
            LOGGER.debug("broadcast start peers=%d", len(self._peers))
            if exclude is None:
                exclude = []

            for connection_id in self._peers.copy():
                LOGGER.debug("broadcast for %s", connection_id)
                if connection_id not in exclude and \
                        self._network.is_connection_handshake_complete(
                            connection_id):
                    LOGGER.info("gossip:broadcast: send %s to %s",
                                get_enum_name(message_type), connection_id)
                    self.send(message_type,
                              gossip_message.SerializeToString(),
                              connection_id,
                              one_way=True)
Exemple #4
0
    def dispatch(self, connection, message, connection_id):
        if message.message_type in self._msg_type_handlers:
            priority = self._priority.get(message.message_type, Priority.LOW)
            message_id = _gen_message_id()

            self._message_information[message_id] = \
                _MessageInformation(
                    connection=connection,
                    connection_id=connection_id,
                    content=message.content,
                    correlation_id=message.correlation_id,
                    message_type=message.message_type,
                    collection=_ManagerCollection(
                        self._msg_type_handlers[message.message_type]))

            self._in_queue.put_nowait((priority, message_id))

            queue_size = self._in_queue.qsize()
            if queue_size > 10:
                LOGGER.debug("Dispatch incoming queue size: %s", queue_size)
        else:
            LOGGER.info("received a message of type %s "
                        "from %s but have no handler for that type",
                        get_enum_name(message.message_type),
                        connection_id)
Exemple #5
0
    def _determine_next(self, message_id, future):
        if future.result().status == HandlerStatus.DROP:
            del self._message_information[message_id]

        elif future.result().status == HandlerStatus.PASS:
            self._process(message_id)

        elif future.result().status == HandlerStatus.RETURN_AND_PASS:
            connection, connection_id, \
                original_message, _ = self._message_information[message_id]

            message = validator_pb2.Message(
                content=future.result().message_out.SerializeToString(),
                correlation_id=original_message.correlation_id,
                message_type=future.result().message_type)
            try:
                self._send_message[connection](msg=message,
                                               connection_id=connection_id)
            except KeyError:
                LOGGER.info("Can't send message %s back to "
                            "%s because connection %s not in dispatcher",
                            get_enum_name(message.message_type), connection_id,
                            connection)
            self._process(message_id)

        elif future.result().status == HandlerStatus.RETURN:
            connection, connection_id,  \
                original_message, _ = self._message_information[message_id]

            del self._message_information[message_id]

            message = validator_pb2.Message(
                content=future.result().message_out.SerializeToString(),
                correlation_id=original_message.correlation_id,
                message_type=future.result().message_type)
            try:
                self._send_message[connection](msg=message,
                                               connection_id=connection_id)
            except KeyError:
                LOGGER.info("Can't send message %s back to "
                            "%s because connection %s not in dispatcher",
                            get_enum_name(message.message_type), connection_id,
                            connection)
        with self._condition:
            if not self._message_information:
                self._condition.notify()
Exemple #6
0
        def do_next(result):
            message_info = self._message_information[message_id]
            LOGGER.debug("do_next: result %s",str(result))
            try:
                # check for a None result
                if result is None:
                    LOGGER.error(
                        "%s preprocessor returned None result for messsage %s",
                        preprocessor,
                        message_id)
                    return
                LOGGER.debug("do_next: status %s",str(result.status))
                # check for result status
                if result.status == HandlerStatus.DROP:
                    del self._message_information[message_id]
                    return

                if result.status == HandlerStatus.RETURN:
                    del self._message_information[message_id]

                    message = validator_pb2.Message(
                        content=result.message_out.SerializeToString(),
                        correlation_id=message_info.correlation_id,
                        message_type=result.message_type)

                    try:
                        self._send_message[message_info.connection](
                            msg=message,
                            connection_id=message_info.connection_id)
                    except KeyError:
                        LOGGER.warning(
                            "Can't send message %s back to "
                            "%s because connection %s not in dispatcher",
                            get_enum_name(message.message_type),
                            message_info.connection_id,
                            message_info.connection)

                    return

                # store the preprocessor result
                self._message_information[message_id] = \
                    _MessageInformation(
                        connection=message_info.connection,
                        connection_id=message_info.connection_id,
                        content=result.content,
                        correlation_id=message_info.correlation_id,
                        collection=message_info.collection,
                        message_type=message_info.message_type)

                self._process_next(message_id)

            except Exception:  # pylint: disable=broad-except
                LOGGER.exception(
                    "Unhandled exception after preprocessing")
Exemple #7
0
        def do_next(result):
            message_info = self._message_information[message_id]

            try:
                # check for a None result
                if result is None:
                    LOGGER.error(
                        "%s preprocessor returned None result for messsage %s",
                        preprocessor,
                        message_id)
                    return

                # check for result status
                if result.status == HandlerStatus.DROP:
                    del self._message_information[message_id]
                    return

                if result.status == HandlerStatus.RETURN:
                    del self._message_information[message_id]

                    message = validator_pb2.Message(
                        content=result.message_out.SerializeToString(),
                        correlation_id=message_info.correlation_id,
                        message_type=result.message_type)

                    try:
                        self._send_message[message_info.connection](
                            msg=message,
                            connection_id=message_info.connection_id)
                    except KeyError:
                        LOGGER.warning(
                            "Can't send message %s back to "
                            "%s because connection %s not in dispatcher",
                            get_enum_name(message.message_type),
                            message_info.connection_id,
                            message_info.connection)

                    return

                # store the preprocessor result
                self._message_information[message_id] = \
                    _MessageInformation(
                        connection=message_info.connection,
                        connection_id=message_info.connection_id,
                        content=result.content,
                        correlation_id=message_info.correlation_id,
                        collection=message_info.collection,
                        message_type=message_info.message_type)

                self._process_next(message_id)

            except Exception:  # pylint: disable=broad-except
                LOGGER.exception(
                    "Unhandled exception after preprocessing")
Exemple #8
0
 def notify(self, message_type, message):
     self._queue_backlog(message_type, message)
     active_engine = self._consensus_registry.get_active_engine_info()
     if active_engine is not None:
         for (queued_type, queued_msg) in self._drain_backlog():
             try:
                 self._service.send(queued_type, bytes(queued_msg),
                                    active_engine.connection_id).result(
                                        timeout=NOTIFICATION_TIMEOUT)
             except FutureTimeoutError:
                 LOGGER.warning("Consensus notification %s timed out",
                                get_enum_name(queued_type))
Exemple #9
0
 def dispatch(self, connection, message, connection_id):
     if message.message_type in self._msg_type_handlers:
         message_id = _gen_message_id()
         self._message_information[message_id] = (
             connection, connection_id, message,
             _ManagerCollection(
                 self._msg_type_handlers[message.message_type]))
         self._in_queue.put_nowait(message_id)
     else:
         LOGGER.info(
             "received a message of type %s "
             "from %s but have no handler for that type",
             get_enum_name(message.message_type), connection_id)
Exemple #10
0
 def notify(self, message_type, message):
     self._queue_backlog(message_type, message)
     active_engine = self._consensus_registry.get_active_engine_info()
     if active_engine is not None:
         for (queued_type, queued_msg) in self._drain_backlog():
             try:
                 self._service.send(
                     queued_type,
                     bytes(queued_msg),
                     active_engine.connection_id
                 ).result(timeout=NOTIFICATION_TIMEOUT)
             except FutureTimeoutError:
                 LOGGER.warning(
                     "Consensus notification %s timed out",
                     get_enum_name(queued_type))
Exemple #11
0
 def dispatch(self, identity, message):
     if message.message_type in self._msg_type_handlers:
         message_id = _gen_message_id()
         self._message_information[message_id] = (
             identity,
             message,
             _ManagerCollection(
                 self._msg_type_handlers[message.message_type])
         )
         self._in_queue.put_nowait(message_id)
     else:
         LOGGER.info("received a message of type %s "
                     "from %s but have no handler for that type",
                     get_enum_name(message.message_type),
                     identity)
Exemple #12
0
    def dispatch(self, connection, message, connection_id):
        if message.message_type in self._msg_type_handlers:
            priority = self._priority.get(message.message_type, LOW_PRIORITY)
            message_id = _gen_message_id()
            self._message_information[message_id] = (
                connection, connection_id, message,
                _ManagerCollection(
                    self._msg_type_handlers[message.message_type]))
            self._in_queue.put_nowait((priority, message_id))

            queue_size = self._in_queue.qsize()
            if queue_size > 10:
                LOGGER.debug("Dispatch incoming queue size: %s", queue_size)
        else:
            LOGGER.info(
                "received a message of type %s from %s but have no handler for that type",
                get_enum_name(message.message_type), connection_id)
Exemple #13
0
    def _determine_next(self, message_id, future):
        try:
            res = future.result(timeout=self._timeout)
        except TimeoutError:
            LOGGER.exception("Dispatcher timeout waiting on handler result.")
            raise

        if res.status == HandlerStatus.DROP:
            del self._message_information[message_id]

        elif res.status == HandlerStatus.PASS:
            self._process(message_id)

        elif res.status == HandlerStatus.RETURN_AND_PASS:
            connection, connection_id, \
                original_message, _ = self._message_information[message_id]

            message = validator_pb2.Message(
                content=res.message_out.SerializeToString(),
                correlation_id=original_message.correlation_id,
                message_type=res.message_type)
            try:
                self._send_message[connection](msg=message,
                                               connection_id=connection_id)
            except KeyError:
                LOGGER.info(
                    "Can't send message %s back to "
                    "%s because connection %s not in dispatcher",
                    get_enum_name(message.message_type), connection_id,
                    connection)
            self._process(message_id)

        elif res.status == HandlerStatus.RETURN:
            connection, connection_id,  \
                original_message, _ = self._message_information[message_id]

            del self._message_information[message_id]

            message = validator_pb2.Message(
                content=res.message_out.SerializeToString(),
                correlation_id=original_message.correlation_id,
                message_type=res.message_type)
            try:
                self._send_message[connection](msg=message,
                                               connection_id=connection_id)
            except KeyError:
                LOGGER.info(
                    "Can't send message %s back to "
                    "%s because connection %s not in dispatcher",
                    get_enum_name(message.message_type), connection_id,
                    connection)

        elif res.status == HandlerStatus.RETURN_AND_CLOSE:
            connection, connection_id,  \
                original_message, _ = self._message_information[message_id]

            del self._message_information[message_id]

            message = validator_pb2.Message(
                content=res.message_out.SerializeToString(),
                correlation_id=original_message.correlation_id,
                message_type=res.message_type)
            try:
                self._send_last_message[connection](
                    msg=message, connection_id=connection_id)
            except KeyError:
                LOGGER.info(
                    "Can't send last message %s back to "
                    "%s because connection %s not in dispatcher",
                    get_enum_name(message.message_type), connection_id,
                    connection)
        with self._condition:
            if not self._message_information:
                self._condition.notify()
Exemple #14
0
    def _determine_next(self, message_id, future):
        try:
            res = future.result(timeout=self._timeout)
        except TimeoutError:
            LOGGER.exception("Dispatcher timeout waiting on handler result.")
            raise

        if res is None:
            LOGGER.debug('Ignoring None handler result, likely due to an '
                         'unhandled error while executing the handler')
            return

        if res.status == HandlerStatus.DROP:
            del self._message_information[message_id]

        elif res.status == HandlerStatus.PASS:
            self._process(message_id)

        elif res.status == HandlerStatus.RETURN_AND_PASS:
            connection, connection_id, \
                original_message, _ = self._message_information[message_id]

            if res.message_out and res.message_type:
                message = validator_pb2.Message(
                    content=res.message_out.SerializeToString(),
                    correlation_id=original_message.correlation_id,
                    message_type=res.message_type)
                try:
                    self._send_message[connection](msg=message,
                                                   connection_id=connection_id)
                except KeyError:
                    LOGGER.info("Can't send message %s back to "
                                "%s because connection %s not in dispatcher",
                                get_enum_name(message.message_type),
                                connection_id,
                                connection)
                self._process(message_id)
            else:
                LOGGER.error("HandlerResult with status of RETURN_AND_PASS "
                             "is missing message_out or message_type")

        elif res.status == HandlerStatus.RETURN:
            connection, connection_id,  \
                original_message, _ = self._message_information[message_id]

            del self._message_information[message_id]

            if res.message_out and res.message_type:
                message = validator_pb2.Message(
                    content=res.message_out.SerializeToString(),
                    correlation_id=original_message.correlation_id,
                    message_type=res.message_type)
                try:
                    self._send_message[connection](msg=message,
                                                   connection_id=connection_id)
                except KeyError:
                    LOGGER.info("Can't send message %s back to "
                                "%s because connection %s not in dispatcher",
                                get_enum_name(message.message_type),
                                connection_id,
                                connection)
            else:
                LOGGER.error("HandlerResult with status of RETURN "
                             "is missing message_out or message_type")

        elif res.status == HandlerStatus.RETURN_AND_CLOSE:
            connection, connection_id,  \
                original_message, _ = self._message_information[message_id]

            del self._message_information[message_id]

            if res.message_out and res.message_type:
                message = validator_pb2.Message(
                    content=res.message_out.SerializeToString(),
                    correlation_id=original_message.correlation_id,
                    message_type=res.message_type)
                try:
                    self._send_last_message[connection](
                        msg=message,
                        connection_id=connection_id)
                except KeyError:
                    LOGGER.info("Can't send last message %s back to "
                                "%s because connection %s not in dispatcher",
                                get_enum_name(message.message_type),
                                connection_id,
                                connection)
            else:
                LOGGER.error("HandlerResult with status of RETURN_AND_CLOSE "
                             "is missing message_out or message_type")
        with self._condition:
            if not self._message_information:
                self._condition.notify()
Exemple #15
0
    def _determine_next(self, message_id, result):
        if result is None:
            LOGGER.debug('Ignoring None handler result, likely due to an '
                         'unhandled error while executing the handler')
            return

        if result.status == HandlerStatus.DROP:
            del self._message_information[message_id]

        elif result.status == HandlerStatus.PASS:
            self._process_next(message_id)

        elif result.status == HandlerStatus.RETURN_AND_PASS:
            message_info = self._message_information[message_id]

            if result.message_out and result.message_type:
                message = validator_pb2.Message(
                    content=result.message_out.SerializeToString(),
                    correlation_id=message_info.correlation_id,
                    message_type=result.message_type)
                try:
                    self._send_message[message_info.connection](
                        msg=message, connection_id=message_info.connection_id)
                except KeyError:
                    LOGGER.warning(
                        "Can't send message %s back to "
                        "%s because connection %s not in dispatcher",
                        get_enum_name(message.message_type),
                        message_info.connection_id, message_info.connection)

                self._process_next(message_id)
            else:
                LOGGER.error("HandlerResult with status of RETURN_AND_PASS "
                             "is missing message_out or message_type")

        elif result.status == HandlerStatus.RETURN:
            message_info = self._message_information[message_id]

            del self._message_information[message_id]

            if result.message_out and result.message_type:
                message = validator_pb2.Message(
                    content=result.message_out.SerializeToString(),
                    correlation_id=message_info.correlation_id,
                    message_type=result.message_type)
                try:
                    self._send_message[message_info.connection](
                        msg=message, connection_id=message_info.connection_id)
                except KeyError:
                    LOGGER.warning(
                        "Can't send message %s back to "
                        "%s because connection %s not in dispatcher",
                        get_enum_name(message.message_type),
                        message_info.connection_id, message_info.connection)
            else:
                LOGGER.error("HandlerResult with status of RETURN "
                             "is missing message_out or message_type")

        elif result.status == HandlerStatus.RETURN_AND_CLOSE:
            message_info = self._message_information[message_id]

            del self._message_information[message_id]

            if result.message_out and result.message_type:
                message = validator_pb2.Message(
                    content=result.message_out.SerializeToString(),
                    correlation_id=message_info.correlation_id,
                    message_type=result.message_type)
                try:
                    LOGGER.warning(
                        "Sending hang-up in reply to %s to connection %s",
                        get_enum_name(message_info.message_type),
                        message_info.connection_id)
                    self._send_last_message[message_info.connection](
                        msg=message, connection_id=message_info.connection_id)
                except KeyError:
                    LOGGER.warning(
                        "Can't send last message %s back to "
                        "%s because connection %s not in dispatcher",
                        get_enum_name(message.message_type),
                        message_info.connection_id, message_info.connection)
            else:
                LOGGER.error("HandlerResult with status of RETURN_AND_CLOSE "
                             "is missing message_out or message_type")
        with self._condition:
            if not self._message_information:
                self._condition.notify()
Exemple #16
0
    def _determine_next(self, message_id, result):
        if result is None:
            LOGGER.debug('Ignoring None handler result, likely due to an '
                         'unhandled error while executing the handler')
            return

        if result.status == HandlerStatus.DROP:
            del self._message_information[message_id]

        elif result.status == HandlerStatus.PASS:
            self._process_next(message_id)

        elif result.status == HandlerStatus.RETURN_AND_PASS:
            message_info = self._message_information[message_id]

            if result.message_out and result.message_type:
                message = validator_pb2.Message(
                    content=result.message_out.SerializeToString(),
                    correlation_id=message_info.correlation_id,
                    message_type=result.message_type)
                try:
                    self._send_message[message_info.connection](
                        msg=message,
                        connection_id=message_info.connection_id)
                except KeyError:
                    LOGGER.warning(
                        "Can't send message %s back to "
                        "%s because connection %s not in dispatcher",
                        get_enum_name(message.message_type),
                        message_info.connection_id,
                        message_info.connection)

                self._process_next(message_id)
            else:
                LOGGER.error("HandlerResult with status of RETURN_AND_PASS "
                             "is missing message_out or message_type")

        elif result.status == HandlerStatus.RETURN:
            message_info = self._message_information[message_id]

            del self._message_information[message_id]

            if result.message_out and result.message_type:
                message = validator_pb2.Message(
                    content=result.message_out.SerializeToString(),
                    correlation_id=message_info.correlation_id,
                    message_type=result.message_type)
                try:
                    self._send_message[message_info.connection](
                        msg=message,
                        connection_id=message_info.connection_id)
                except KeyError:
                    LOGGER.warning(
                        "Can't send message %s back to "
                        "%s because connection %s not in dispatcher",
                        get_enum_name(message.message_type),
                        message_info.connection_id,
                        message_info.connection)
            else:
                LOGGER.error("HandlerResult with status of RETURN "
                             "is missing message_out or message_type")

        elif result.status == HandlerStatus.RETURN_AND_CLOSE:
            message_info = self._message_information[message_id]

            del self._message_information[message_id]

            if result.message_out and result.message_type:
                message = validator_pb2.Message(
                    content=result.message_out.SerializeToString(),
                    correlation_id=message_info.correlation_id,
                    message_type=result.message_type)
                try:
                    LOGGER.warning(
                        "Sending hang-up in reply to %s to connection %s",
                        get_enum_name(message_info.message_type),
                        message_info.connection_id)
                    self._send_last_message[message_info.connection](
                        msg=message,
                        connection_id=message_info.connection_id)
                except KeyError:
                    LOGGER.warning(
                        "Can't send last message %s back to "
                        "%s because connection %s not in dispatcher",
                        get_enum_name(message.message_type),
                        message_info.connection_id,
                        message_info.connection)
            else:
                LOGGER.error("HandlerResult with status of RETURN_AND_CLOSE "
                             "is missing message_out or message_type")
        with self._condition:
            if not self._message_information:
                self._condition.notify()