From b221a135dce8d74f35f4be1876ae3ca5d58deee9 Mon Sep 17 00:00:00 2001 From: aMahanna Date: Fri, 3 Dec 2021 14:23:37 -0500 Subject: [PATCH 01/11] new: draft for host fallback support --- arango/connection.py | 89 +++++++++++++++++++++----------------------- arango/resolver.py | 28 +++++++++++--- 2 files changed, 65 insertions(+), 52 deletions(-) diff --git a/arango/connection.py b/arango/connection.py index 658e43fb..85485454 100644 --- a/arango/connection.py +++ b/arango/connection.py @@ -9,10 +9,10 @@ import sys import time from abc import abstractmethod -from typing import Any, Callable, Optional, Sequence, Union +from typing import Any, Callable, Optional, Sequence, Tuple, Union import jwt -from requests import Session +from requests import ConnectionError, Session from requests_toolbelt import MultipartEncoder from arango.exceptions import JWTAuthError, ServerConnectionError @@ -110,6 +110,42 @@ def prep_response(self, resp: Response, deserialize: bool = True) -> Response: resp.is_success = http_ok and resp.error_code is None return resp + def process_response( + self, host_index: int, request: Request, auth: Optional[Tuple[str, str]] = None + ) -> Response: + """Execute a request until a valid response has been returned. + + :param host_index: The index of the first host to try + :type host_index: int + :param request: HTTP request. + :type request: arango.request.Request + :return: HTTP response. + :rtype: arango.response.Response + """ + tries = 0 + while tries < self._host_resolver.max_tries: + try: + resp = self._http.send_request( + session=self._sessions[host_index], + method=request.method, + url=self._url_prefixes[host_index] + request.endpoint, + params=request.params, + data=self.normalize_data(request.data), + headers=request.headers, + auth=auth, + ) + + return self.prep_response(resp, request.deserialize) + except ConnectionError: + tries += 1 + host_index = self._host_resolver.get_host_index( + prev_host_index=host_index + ) + + raise ConnectionAbortedError( + "Unable to establish connection to host(s) within limit" + ) + def prep_bulk_err_response(self, parent_response: Response, body: Json) -> Response: """Build and return a bulk error response. @@ -227,16 +263,7 @@ def send_request(self, request: Request) -> Response: :rtype: arango.response.Response """ host_index = self._host_resolver.get_host_index() - resp = self._http.send_request( - session=self._sessions[host_index], - method=request.method, - url=self._url_prefixes[host_index] + request.endpoint, - params=request.params, - data=self.normalize_data(request.data), - headers=request.headers, - auth=self._auth, - ) - return self.prep_response(resp, request.deserialize) + return self.process_response(host_index, request, auth=self._auth) class JwtConnection(BaseConnection): @@ -302,15 +329,7 @@ def send_request(self, request: Request) -> Response: if self._auth_header is not None: request.headers["Authorization"] = self._auth_header - resp = self._http.send_request( - session=self._sessions[host_index], - method=request.method, - url=self._url_prefixes[host_index] + request.endpoint, - params=request.params, - data=self.normalize_data(request.data), - headers=request.headers, - ) - resp = self.prep_response(resp, request.deserialize) + resp = self.process_response(host_index, request) # Refresh the token and retry on HTTP 401 and error code 11. if resp.error_code != 11 or resp.status_code != 401: @@ -325,15 +344,7 @@ def send_request(self, request: Request) -> Response: if self._auth_header is not None: request.headers["Authorization"] = self._auth_header - resp = self._http.send_request( - session=self._sessions[host_index], - method=request.method, - url=self._url_prefixes[host_index] + request.endpoint, - params=request.params, - data=self.normalize_data(request.data), - headers=request.headers, - ) - return self.prep_response(resp, request.deserialize) + return self.process_response(host_index, request) def refresh_token(self) -> None: """Get a new JWT token for the current user (cannot be a superuser). @@ -349,13 +360,7 @@ def refresh_token(self) -> None: host_index = self._host_resolver.get_host_index() - resp = self._http.send_request( - session=self._sessions[host_index], - method=request.method, - url=self._url_prefixes[host_index] + request.endpoint, - data=self.normalize_data(request.data), - ) - resp = self.prep_response(resp) + resp = self.process_response(host_index, request) if not resp.is_success: raise JWTAuthError(resp, request) @@ -429,12 +434,4 @@ def send_request(self, request: Request) -> Response: host_index = self._host_resolver.get_host_index() request.headers["Authorization"] = self._auth_header - resp = self._http.send_request( - session=self._sessions[host_index], - method=request.method, - url=self._url_prefixes[host_index] + request.endpoint, - params=request.params, - data=self.normalize_data(request.data), - headers=request.headers, - ) - return self.prep_response(resp, request.deserialize) + return self.process_response(host_index, request) diff --git a/arango/resolver.py b/arango/resolver.py index 72dfe8bb..96f5f16a 100644 --- a/arango/resolver.py +++ b/arango/resolver.py @@ -7,20 +7,24 @@ import random from abc import ABC, abstractmethod +from typing import Optional, Set class HostResolver(ABC): # pragma: no cover """Abstract base class for host resolvers.""" + def __init__(self) -> None: + self.max_tries: int = 3 + @abstractmethod - def get_host_index(self) -> int: + def get_host_index(self, prev_host_index: Optional[int] = None) -> int: raise NotImplementedError class SingleHostResolver(HostResolver): """Single host resolver.""" - def get_host_index(self) -> int: + def get_host_index(self, prev_host_index: Optional[int] = None) -> int: return 0 @@ -28,19 +32,31 @@ class RandomHostResolver(HostResolver): """Random host resolver.""" def __init__(self, host_count: int) -> None: - self._max = host_count - 1 + self.max_tries = host_count * 3 + self._count = host_count + self._prev_host_indexes: Set[int] = set() + + def get_host_index(self, prev_host_index: Optional[int] = None) -> int: + if prev_host_index: + self._prev_host_indexes.add(prev_host_index) + if len(self._prev_host_indexes) == self._count: + self._prev_host_indexes.clear() + + host_index = None + while host_index is None or host_index in self._prev_host_indexes: + host_index = random.randint(0, self._count - 1) - def get_host_index(self) -> int: - return random.randint(0, self._max) + return host_index class RoundRobinHostResolver(HostResolver): """Round-robin host resolver.""" def __init__(self, host_count: int) -> None: + self._max_tries = host_count * 3 self._index = -1 self._count = host_count - def get_host_index(self) -> int: + def get_host_index(self, prev_host_index: Optional[int] = None) -> int: self._index = (self._index + 1) % self._count return self._index From 14ab9ac87b9cd8768ab0023f792b293b67fad3a6 Mon Sep 17 00:00:00 2001 From: aMahanna Date: Fri, 3 Dec 2021 14:28:24 -0500 Subject: [PATCH 02/11] fix: typo --- arango/resolver.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arango/resolver.py b/arango/resolver.py index 96f5f16a..b2e8605f 100644 --- a/arango/resolver.py +++ b/arango/resolver.py @@ -53,7 +53,7 @@ class RoundRobinHostResolver(HostResolver): """Round-robin host resolver.""" def __init__(self, host_count: int) -> None: - self._max_tries = host_count * 3 + self.max_tries = host_count * 3 self._index = -1 self._count = host_count From b8e63403090f4bc81189b654c931aacdf7f87b96 Mon Sep 17 00:00:00 2001 From: aMahanna Date: Fri, 3 Dec 2021 20:27:31 -0500 Subject: [PATCH 03/11] fix: control statement --- arango/resolver.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arango/resolver.py b/arango/resolver.py index b2e8605f..a74af8cf 100644 --- a/arango/resolver.py +++ b/arango/resolver.py @@ -37,7 +37,7 @@ def __init__(self, host_count: int) -> None: self._prev_host_indexes: Set[int] = set() def get_host_index(self, prev_host_index: Optional[int] = None) -> int: - if prev_host_index: + if prev_host_index is not None: self._prev_host_indexes.add(prev_host_index) if len(self._prev_host_indexes) == self._count: self._prev_host_indexes.clear() From 006a89a23629b676de4b3c626a8880131bb2056a Mon Sep 17 00:00:00 2001 From: aMahanna Date: Fri, 3 Dec 2021 20:28:17 -0500 Subject: [PATCH 04/11] update: test_resolver_random_host --- tests/test_resolver.py | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/tests/test_resolver.py b/tests/test_resolver.py index 0598addd..f21aaaff 100644 --- a/tests/test_resolver.py +++ b/tests/test_resolver.py @@ -16,6 +16,18 @@ def test_resolver_random_host(): for _ in range(20): assert 0 <= resolver.get_host_index() < 10 + resolver = RandomHostResolver(2) + index_a = resolver.get_host_index() + index_b = resolver.get_host_index(prev_host_index=index_a) + index_c = resolver.get_host_index(prev_host_index=index_b) + assert index_c in [index_a, index_b] + + resolver = RandomHostResolver(3) + index_a = resolver.get_host_index() + index_b = resolver.get_host_index(prev_host_index=index_a) + index_c = resolver.get_host_index(prev_host_index=index_b) + assert index_c not in [index_a, index_b] + def test_resolver_round_robin(): resolver = RoundRobinHostResolver(10) From 00ec73efa28f24d5a5dae8187564a78761971b3a Mon Sep 17 00:00:00 2001 From: aMahanna Date: Fri, 3 Dec 2021 20:36:00 -0500 Subject: [PATCH 05/11] cleanup: RandomHostResolver --- arango/resolver.py | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/arango/resolver.py b/arango/resolver.py index a74af8cf..78e43981 100644 --- a/arango/resolver.py +++ b/arango/resolver.py @@ -32,19 +32,20 @@ class RandomHostResolver(HostResolver): """Random host resolver.""" def __init__(self, host_count: int) -> None: + self._max = host_count - 1 self.max_tries = host_count * 3 - self._count = host_count self._prev_host_indexes: Set[int] = set() def get_host_index(self, prev_host_index: Optional[int] = None) -> int: if prev_host_index is not None: - self._prev_host_indexes.add(prev_host_index) - if len(self._prev_host_indexes) == self._count: + if len(self._prev_host_indexes) == self._max: self._prev_host_indexes.clear() + self._prev_host_indexes.add(prev_host_index) + host_index = None while host_index is None or host_index in self._prev_host_indexes: - host_index = random.randint(0, self._count - 1) + host_index = random.randint(0, self._max) return host_index From e2ad59ff297851691e8e5ee65b0ecaf7d2450f10 Mon Sep 17 00:00:00 2001 From: aMahanna Date: Fri, 3 Dec 2021 20:39:12 -0500 Subject: [PATCH 06/11] fix: max_tries to _max_tries (switched to protected syntax) --- arango/connection.py | 2 +- arango/resolver.py | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/arango/connection.py b/arango/connection.py index 85485454..db00cfe8 100644 --- a/arango/connection.py +++ b/arango/connection.py @@ -123,7 +123,7 @@ def process_response( :rtype: arango.response.Response """ tries = 0 - while tries < self._host_resolver.max_tries: + while tries < self._host_resolver._max_tries: try: resp = self._http.send_request( session=self._sessions[host_index], diff --git a/arango/resolver.py b/arango/resolver.py index 78e43981..03a13a33 100644 --- a/arango/resolver.py +++ b/arango/resolver.py @@ -14,7 +14,7 @@ class HostResolver(ABC): # pragma: no cover """Abstract base class for host resolvers.""" def __init__(self) -> None: - self.max_tries: int = 3 + self._max_tries: int = 3 @abstractmethod def get_host_index(self, prev_host_index: Optional[int] = None) -> int: @@ -33,7 +33,7 @@ class RandomHostResolver(HostResolver): def __init__(self, host_count: int) -> None: self._max = host_count - 1 - self.max_tries = host_count * 3 + self._max_tries = host_count * 3 self._prev_host_indexes: Set[int] = set() def get_host_index(self, prev_host_index: Optional[int] = None) -> int: @@ -54,7 +54,7 @@ class RoundRobinHostResolver(HostResolver): """Round-robin host resolver.""" def __init__(self, host_count: int) -> None: - self.max_tries = host_count * 3 + self._max_tries = host_count * 3 self._index = -1 self._count = host_count From 90f30979f51a194addfa331c31db5f874d821c23 Mon Sep 17 00:00:00 2001 From: aMahanna Date: Sun, 5 Dec 2021 16:17:17 -0500 Subject: [PATCH 07/11] chg: address comments --- arango/client.py | 9 ++++++-- arango/connection.py | 30 ++++++++++++++++----------- arango/resolver.py | 47 ++++++++++++++++++++++-------------------- tests/test_resolver.py | 28 ++++++++++++++++++------- 4 files changed, 70 insertions(+), 44 deletions(-) diff --git a/arango/client.py b/arango/client.py index eec64a7b..2751a497 100644 --- a/arango/client.py +++ b/arango/client.py @@ -31,6 +31,10 @@ class ArangoClient: multiple host URLs are provided). Accepted values are "roundrobin" and "random". Any other value defaults to round robin. :type host_resolver: str + :param resolver_max_tries: Number of attempts to process an HTTP request + before throwing a ConnectionAbortedError. Must not be lower than the + number of hosts. + :type resolver_max_tries: int :param http_client: User-defined HTTP client. :type http_client: arango.http.HTTPClient :param serializer: User-defined JSON serializer. Must be a callable @@ -48,6 +52,7 @@ def __init__( self, hosts: Union[str, Sequence[str]] = "http://127.0.0.1:8529", host_resolver: str = "roundrobin", + resolver_max_tries: Optional[int] = None, http_client: Optional[HTTPClient] = None, serializer: Callable[..., str] = lambda x: dumps(x), deserializer: Callable[[str], Any] = lambda x: loads(x), @@ -63,9 +68,9 @@ def __init__( if host_count == 1: self._host_resolver = SingleHostResolver() elif host_resolver == "random": - self._host_resolver = RandomHostResolver(host_count) + self._host_resolver = RandomHostResolver(host_count, resolver_max_tries) else: - self._host_resolver = RoundRobinHostResolver(host_count) + self._host_resolver = RoundRobinHostResolver(host_count, resolver_max_tries) self._http = http_client or DefaultHTTPClient() self._serializer = serializer diff --git a/arango/connection.py b/arango/connection.py index db00cfe8..be2bd1cc 100644 --- a/arango/connection.py +++ b/arango/connection.py @@ -6,10 +6,11 @@ "JwtSuperuserConnection", ] +# import logging import sys import time from abc import abstractmethod -from typing import Any, Callable, Optional, Sequence, Tuple, Union +from typing import Any, Callable, Optional, Sequence, Set, Tuple, Union import jwt from requests import ConnectionError, Session @@ -110,7 +111,7 @@ def prep_response(self, resp: Response, deserialize: bool = True) -> Response: resp.is_success = http_ok and resp.error_code is None return resp - def process_response( + def process_request( self, host_index: int, request: Request, auth: Optional[Tuple[str, str]] = None ) -> Response: """Execute a request until a valid response has been returned. @@ -123,7 +124,8 @@ def process_response( :rtype: arango.response.Response """ tries = 0 - while tries < self._host_resolver._max_tries: + indexes_to_filter: Set[int] = set() + while tries < self._host_resolver.max_tries: try: resp = self._http.send_request( session=self._sessions[host_index], @@ -137,13 +139,17 @@ def process_response( return self.prep_response(resp, request.deserialize) except ConnectionError: + # logging.exception("TODO") # TODO + + if len(indexes_to_filter) == self._host_resolver.host_count - 1: + indexes_to_filter.clear() + indexes_to_filter.add(host_index) + + host_index = self._host_resolver.get_host_index(indexes_to_filter) tries += 1 - host_index = self._host_resolver.get_host_index( - prev_host_index=host_index - ) raise ConnectionAbortedError( - "Unable to establish connection to host(s) within limit" + f"Can't connect to host(s) within limit ({self._host_resolver.max_tries})" ) def prep_bulk_err_response(self, parent_response: Response, body: Json) -> Response: @@ -263,7 +269,7 @@ def send_request(self, request: Request) -> Response: :rtype: arango.response.Response """ host_index = self._host_resolver.get_host_index() - return self.process_response(host_index, request, auth=self._auth) + return self.process_request(host_index, request, auth=self._auth) class JwtConnection(BaseConnection): @@ -329,7 +335,7 @@ def send_request(self, request: Request) -> Response: if self._auth_header is not None: request.headers["Authorization"] = self._auth_header - resp = self.process_response(host_index, request) + resp = self.process_request(host_index, request) # Refresh the token and retry on HTTP 401 and error code 11. if resp.error_code != 11 or resp.status_code != 401: @@ -344,7 +350,7 @@ def send_request(self, request: Request) -> Response: if self._auth_header is not None: request.headers["Authorization"] = self._auth_header - return self.process_response(host_index, request) + return self.process_request(host_index, request) def refresh_token(self) -> None: """Get a new JWT token for the current user (cannot be a superuser). @@ -360,7 +366,7 @@ def refresh_token(self) -> None: host_index = self._host_resolver.get_host_index() - resp = self.process_response(host_index, request) + resp = self.process_request(host_index, request) if not resp.is_success: raise JWTAuthError(resp, request) @@ -434,4 +440,4 @@ def send_request(self, request: Request) -> Response: host_index = self._host_resolver.get_host_index() request.headers["Authorization"] = self._auth_header - return self.process_response(host_index, request) + return self.process_request(host_index, request) diff --git a/arango/resolver.py b/arango/resolver.py index 03a13a33..7db6f143 100644 --- a/arango/resolver.py +++ b/arango/resolver.py @@ -13,39 +13,43 @@ class HostResolver(ABC): # pragma: no cover """Abstract base class for host resolvers.""" - def __init__(self) -> None: - self._max_tries: int = 3 + def __init__(self, host_count: int = 1, max_tries: int = 3) -> None: + if max_tries < host_count: + raise ValueError("max_tries cannot be less than host_count") + + self._host_count = host_count + self._max_tries = max_tries @abstractmethod - def get_host_index(self, prev_host_index: Optional[int] = None) -> int: + def get_host_index(self, indexes_to_filter: Set[int] = set()) -> int: raise NotImplementedError + @property + def host_count(self) -> int: + return self._host_count + + @property + def max_tries(self) -> int: + return self._max_tries + class SingleHostResolver(HostResolver): """Single host resolver.""" - def get_host_index(self, prev_host_index: Optional[int] = None) -> int: + def get_host_index(self, indexes_to_filter: Set[int] = set()) -> int: return 0 class RandomHostResolver(HostResolver): """Random host resolver.""" - def __init__(self, host_count: int) -> None: - self._max = host_count - 1 - self._max_tries = host_count * 3 - self._prev_host_indexes: Set[int] = set() - - def get_host_index(self, prev_host_index: Optional[int] = None) -> int: - if prev_host_index is not None: - if len(self._prev_host_indexes) == self._max: - self._prev_host_indexes.clear() - - self._prev_host_indexes.add(prev_host_index) + def __init__(self, host_count: int, max_tries: Optional[int] = None) -> None: + super().__init__(host_count, max_tries or host_count * 3) + def get_host_index(self, indexes_to_filter: Set[int] = set()) -> int: host_index = None - while host_index is None or host_index in self._prev_host_indexes: - host_index = random.randint(0, self._max) + while host_index is None or host_index in indexes_to_filter: + host_index = random.randint(0, self.host_count - 1) return host_index @@ -53,11 +57,10 @@ def get_host_index(self, prev_host_index: Optional[int] = None) -> int: class RoundRobinHostResolver(HostResolver): """Round-robin host resolver.""" - def __init__(self, host_count: int) -> None: - self._max_tries = host_count * 3 + def __init__(self, host_count: int, max_tries: Optional[int] = None) -> None: + super().__init__(host_count, max_tries or host_count * 3) self._index = -1 - self._count = host_count - def get_host_index(self, prev_host_index: Optional[int] = None) -> int: - self._index = (self._index + 1) % self._count + def get_host_index(self, indexes_to_filter: Set[int] = set()) -> int: + self._index = (self._index + 1) % self.host_count return self._index diff --git a/tests/test_resolver.py b/tests/test_resolver.py index f21aaaff..ff5630a1 100644 --- a/tests/test_resolver.py +++ b/tests/test_resolver.py @@ -1,3 +1,7 @@ +from typing import Set + +import pytest + from arango.resolver import ( RandomHostResolver, RoundRobinHostResolver, @@ -5,6 +9,11 @@ ) +def test_bad_resolver(): + with pytest.raises(ValueError): + RandomHostResolver(3, 2) + + def test_resolver_single_host(): resolver = SingleHostResolver() for _ in range(20): @@ -16,16 +25,19 @@ def test_resolver_random_host(): for _ in range(20): assert 0 <= resolver.get_host_index() < 10 - resolver = RandomHostResolver(2) - index_a = resolver.get_host_index() - index_b = resolver.get_host_index(prev_host_index=index_a) - index_c = resolver.get_host_index(prev_host_index=index_b) - assert index_c in [index_a, index_b] - resolver = RandomHostResolver(3) + indexes_to_filter: Set[int] = set() + index_a = resolver.get_host_index() - index_b = resolver.get_host_index(prev_host_index=index_a) - index_c = resolver.get_host_index(prev_host_index=index_b) + indexes_to_filter.add(index_a) + + index_b = resolver.get_host_index(indexes_to_filter) + indexes_to_filter.add(index_b) + assert index_b != index_a + + index_c = resolver.get_host_index(indexes_to_filter) + indexes_to_filter.clear() + indexes_to_filter.add(index_c) assert index_c not in [index_a, index_b] From 1518b3c9892ed58c50d4909e01c6ed546adb8623 Mon Sep 17 00:00:00 2001 From: aMahanna Date: Mon, 6 Dec 2021 12:38:46 -0500 Subject: [PATCH 08/11] cleanup: max_tries --- arango/client.py | 2 +- arango/resolver.py | 7 ++++--- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/arango/client.py b/arango/client.py index 2751a497..71b4eb51 100644 --- a/arango/client.py +++ b/arango/client.py @@ -66,7 +66,7 @@ def __init__( self._host_resolver: HostResolver if host_count == 1: - self._host_resolver = SingleHostResolver() + self._host_resolver = SingleHostResolver(1, resolver_max_tries) elif host_resolver == "random": self._host_resolver = RandomHostResolver(host_count, resolver_max_tries) else: diff --git a/arango/resolver.py b/arango/resolver.py index 7db6f143..e70a8a85 100644 --- a/arango/resolver.py +++ b/arango/resolver.py @@ -13,7 +13,8 @@ class HostResolver(ABC): # pragma: no cover """Abstract base class for host resolvers.""" - def __init__(self, host_count: int = 1, max_tries: int = 3) -> None: + def __init__(self, host_count: int = 1, max_tries: Optional[int] = None) -> None: + max_tries = max_tries or host_count * 3 if max_tries < host_count: raise ValueError("max_tries cannot be less than host_count") @@ -44,7 +45,7 @@ class RandomHostResolver(HostResolver): """Random host resolver.""" def __init__(self, host_count: int, max_tries: Optional[int] = None) -> None: - super().__init__(host_count, max_tries or host_count * 3) + super().__init__(host_count, max_tries) def get_host_index(self, indexes_to_filter: Set[int] = set()) -> int: host_index = None @@ -58,7 +59,7 @@ class RoundRobinHostResolver(HostResolver): """Round-robin host resolver.""" def __init__(self, host_count: int, max_tries: Optional[int] = None) -> None: - super().__init__(host_count, max_tries or host_count * 3) + super().__init__(host_count, max_tries) self._index = -1 def get_host_index(self, indexes_to_filter: Set[int] = set()) -> int: From 711fb449948bff3d506f8c065052e5a3193db261 Mon Sep 17 00:00:00 2001 From: aMahanna Date: Tue, 7 Dec 2021 09:55:26 -0500 Subject: [PATCH 09/11] chg: address comments --- arango/connection.py | 5 +++-- arango/resolver.py | 9 +++++---- 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/arango/connection.py b/arango/connection.py index be2bd1cc..fefd3d85 100644 --- a/arango/connection.py +++ b/arango/connection.py @@ -6,7 +6,7 @@ "JwtSuperuserConnection", ] -# import logging +import logging import sys import time from abc import abstractmethod @@ -139,7 +139,8 @@ def process_request( return self.prep_response(resp, request.deserialize) except ConnectionError: - # logging.exception("TODO") # TODO + url = self._url_prefixes[host_index] + request.endpoint + logging.exception(f"ConnectionError: {url}") if len(indexes_to_filter) == self._host_resolver.host_count - 1: indexes_to_filter.clear() diff --git a/arango/resolver.py b/arango/resolver.py index e70a8a85..06a7aa77 100644 --- a/arango/resolver.py +++ b/arango/resolver.py @@ -22,7 +22,7 @@ def __init__(self, host_count: int = 1, max_tries: Optional[int] = None) -> None self._max_tries = max_tries @abstractmethod - def get_host_index(self, indexes_to_filter: Set[int] = set()) -> int: + def get_host_index(self, indexes_to_filter: Optional[Set[int]] = None) -> int: raise NotImplementedError @property @@ -37,7 +37,7 @@ def max_tries(self) -> int: class SingleHostResolver(HostResolver): """Single host resolver.""" - def get_host_index(self, indexes_to_filter: Set[int] = set()) -> int: + def get_host_index(self, indexes_to_filter: Optional[Set[int]] = None) -> int: return 0 @@ -47,8 +47,9 @@ class RandomHostResolver(HostResolver): def __init__(self, host_count: int, max_tries: Optional[int] = None) -> None: super().__init__(host_count, max_tries) - def get_host_index(self, indexes_to_filter: Set[int] = set()) -> int: + def get_host_index(self, indexes_to_filter: Optional[Set[int]] = None) -> int: host_index = None + indexes_to_filter = indexes_to_filter or set() while host_index is None or host_index in indexes_to_filter: host_index = random.randint(0, self.host_count - 1) @@ -62,6 +63,6 @@ def __init__(self, host_count: int, max_tries: Optional[int] = None) -> None: super().__init__(host_count, max_tries) self._index = -1 - def get_host_index(self, indexes_to_filter: Set[int] = set()) -> int: + def get_host_index(self, indexes_to_filter: Optional[Set[int]] = None) -> int: self._index = (self._index + 1) % self.host_count return self._index From 2affd12ce3dd36e15e638a4028a451deb85e3356 Mon Sep 17 00:00:00 2001 From: aMahanna Date: Wed, 8 Dec 2021 10:33:12 -0500 Subject: [PATCH 10/11] chg: logging.error --- arango/connection.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arango/connection.py b/arango/connection.py index fefd3d85..4ededd58 100644 --- a/arango/connection.py +++ b/arango/connection.py @@ -140,7 +140,7 @@ def process_request( return self.prep_response(resp, request.deserialize) except ConnectionError: url = self._url_prefixes[host_index] + request.endpoint - logging.exception(f"ConnectionError: {url}") + logging.error(f"ConnectionError: {url}") if len(indexes_to_filter) == self._host_resolver.host_count - 1: indexes_to_filter.clear() From dbcc3d7517b02e971608d28a459120dd43d34ee7 Mon Sep 17 00:00:00 2001 From: aMahanna Date: Thu, 9 Dec 2021 21:18:03 -0500 Subject: [PATCH 11/11] new: logging.debug --- arango/connection.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arango/connection.py b/arango/connection.py index 4ededd58..d49edfe3 100644 --- a/arango/connection.py +++ b/arango/connection.py @@ -140,7 +140,7 @@ def process_request( return self.prep_response(resp, request.deserialize) except ConnectionError: url = self._url_prefixes[host_index] + request.endpoint - logging.error(f"ConnectionError: {url}") + logging.debug(f"ConnectionError: {url}") if len(indexes_to_filter) == self._host_resolver.host_count - 1: indexes_to_filter.clear()