def update_routing_table(self):
        """ Update the routing table from the first router able to provide
        valid routing information.
        """
        # copied because it can be modified
        copy_of_routers = list(self.routing_table.routers)

        has_tried_initial_routers = False
        if self.missing_writer:
            has_tried_initial_routers = True
            if self.update_routing_table_with_routers(resolve(self.initial_address)):
                return

        if self.update_routing_table_with_routers(copy_of_routers):
            return

        if not has_tried_initial_routers:
            initial_routers = resolve(self.initial_address)
            for router in copy_of_routers:
                if router in initial_routers:
                    initial_routers.remove(router)
            if initial_routers:
                if self.update_routing_table_with_routers(initial_routers):
                    return

        # None of the routers have been successful, so just fail
        raise ServiceUnavailable("Unable to retrieve routing information")
    def fetch_routing_info(self, address):
        """ Fetch raw routing info from a given router address.

        :param address: router address
        :return: list of routing records or
                 None if no connection could be established
        :raise ServiceUnavailable: if the server does not support routing or
                                   if routing support is broken
        """
        try:
            with RoutingSession(lambda _: self.acquire_direct(address), access_mode=None) as session:
                return list(session.run("ignored", self.routing_context))
        except CypherError as error:
            if error.code == "Neo.ClientError.Procedure.ProcedureNotFound":
                raise ServiceUnavailable("Server {!r} does not support routing".format(address))
            else:
                raise ServiceUnavailable("Routing support broken on server {!r}".format(address))
        except ServiceUnavailable:
            self.deactivate(address)
            return None
示例#3
0
    def fetch_routing_info(self, address):
        """ Fetch raw routing info from a given router address.

        :param address: router address
        :return: list of routing records or
                 None if no connection could be established
        :raise ServiceUnavailable: if the server does not support routing or
                                   if routing support is broken
        """
        class RoutingInfoUpdateSession(Session):
            def __run__(self, _, routing_context):
                if ServerVersion.from_str(
                        self._connection.server.version).at_least_version(
                            3, 2):
                    statement, parameters = (
                        "CALL dbms.cluster.routing.getRoutingTable({context})",
                        {
                            "context": routing_context
                        })
                else:
                    statement, parameters = "CALL dbms.cluster.routing.getServers", {}
                return self._run(statement, parameters)

        try:
            with RoutingInfoUpdateSession(
                    lambda _: self.acquire_direct(address),
                    access_mode=None) as session:
                return list(session.run("ignored", self.routing_context))
        except CypherError as error:
            if error.code == "Neo.ClientError.Procedure.ProcedureNotFound":
                raise ServiceUnavailable(
                    "Server {!r} does not support routing".format(address))
            else:
                raise ServiceUnavailable(
                    "Routing support broken on server {!r}".format(address))
        except ServiceUnavailable:
            self.deactivate(address)
            return None
示例#4
0
    def update_routing_table(self):
        """ Update the routing table from the first router able to provide
        valid routing information.
        """
        # copied because it can be modified
        existing_routers = list(self.routing_table.routers)

        has_tried_initial_routers = False
        if self.missing_writer:
            has_tried_initial_routers = True
            if self.update_routing_table_from(self.initial_address):
                return

        if self.update_routing_table_from(*existing_routers):
            return

        if not has_tried_initial_routers and self.initial_address not in existing_routers:
            if self.update_routing_table_from(self.initial_address):
                return

        # None of the routers have been successful, so just fail
        raise ServiceUnavailable("Unable to retrieve routing information")