From e489ba3d64638c85ca87d4df6a016a722fadd9df Mon Sep 17 00:00:00 2001 From: Rouven Bauer Date: Wed, 7 Apr 2021 17:23:24 +0200 Subject: [PATCH] Try all routers before giving up --- neo4j/io/__init__.py | 19 +++++++++++++------ tests/stub/test_routingdriver.py | 6 ++---- 2 files changed, 15 insertions(+), 10 deletions(-) diff --git a/neo4j/io/__init__.py b/neo4j/io/__init__.py index 5d323d45..9b5ed842 100644 --- a/neo4j/io/__init__.py +++ b/neo4j/io/__init__.py @@ -754,10 +754,13 @@ def update_routing_table_from(self, *routers, database=None, """ log.debug("Attempting to update routing table from {}".format(", ".join(map(repr, routers)))) for router in routers: - new_routing_table = self.fetch_routing_table( - address=router, timeout=self.pool_config.connection_timeout, - database=database, bookmarks=bookmarks - ) + try: + new_routing_table = self.fetch_routing_table( + address=router, timeout=self.pool_config.connection_timeout, + database=database, bookmarks=bookmarks + ) + except BoltRoutingError: + continue if new_routing_table is not None: self.routing_tables[database].update(new_routing_table) log.debug("[#0000] C: address={!r} ({!r})".format(router, self.routing_tables[database])) @@ -786,8 +789,12 @@ def update_routing_table(self, *, database, bookmarks): ): # Why is only the first initial routing address used? return - if self.update_routing_table_from(*existing_routers, database=database, - bookmarks=bookmarks): + if self.update_routing_table_from( + *[r for r in existing_routers + if (not has_tried_initial_routers + or r != self.first_initial_routing_address)], + database=database, bookmarks=bookmarks + ): return if (not has_tried_initial_routers diff --git a/tests/stub/test_routingdriver.py b/tests/stub/test_routingdriver.py index acfec4ea..d1319d8c 100644 --- a/tests/stub/test_routingdriver.py +++ b/tests/stub/test_routingdriver.py @@ -34,13 +34,11 @@ ) from neo4j.exceptions import ( ServiceUnavailable, - ClientError, TransientError, SessionExpired, ConfigurationError, ) from neo4j._exceptions import ( - BoltRoutingError, BoltSecurityError, ) from tests.stub.conftest import StubCluster @@ -214,7 +212,7 @@ def test_cannot_discover_servers_on_non_router(driver_info, test_script): def test_cannot_discover_servers_on_silent_router(driver_info, test_script): # python -m pytest tests/stub/test_routingdriver.py -s -v -k test_cannot_discover_servers_on_silent_router with StubCluster(test_script): - with pytest.raises(BoltRoutingError): + with pytest.raises(ServiceUnavailable, match="routing"): with GraphDatabase.driver(driver_info["uri_neo4j"], auth=driver_info["auth_token"]) as driver: assert isinstance(driver, Neo4jDriver) driver._pool.update_routing_table(database=None, bookmarks=None) @@ -532,7 +530,7 @@ def test_should_serve_read_when_missing_writer(driver_info, test_scripts, test_r def test_should_error_when_missing_reader(driver_info, test_script): # python -m pytest tests/stub/test_routingdriver.py -s -v -k test_should_error_when_missing_reader with StubCluster(test_script): - with pytest.raises(BoltRoutingError): + with pytest.raises(ServiceUnavailable, match="routing"): with GraphDatabase.driver(driver_info["uri_neo4j"], auth=driver_info["auth_token"]) as driver: assert isinstance(driver, Neo4jDriver) driver._pool.update_routing_table(database=None, bookmarks=None)