fix(sdk): make retries safe and deterministic
This commit is contained in:
1 parent
e29b3c9648
commit
bfe068b367
8 files changed
+567
-52
No files matched your search
+15
-30
@@ -4,10 +4,12 @@ from __future__ import annotations
|
||||
|
||||
import time
|
||||
import warnings
|
||||
from typing import Any, Dict, List, Optional, Union
|
||||
from typing import Any, Dict, Optional, Union
|
||||
|
||||
import requests
|
||||
|
||||
from ._retry import require_max_retries
|
||||
from ._sync_http import request_with_retries
|
||||
from .crypto import compute_chain_hash, compute_payload_hash, sign_eor
|
||||
from .errors import ElydoraError
|
||||
from .integration_types import require_integration_type
|
||||
@@ -19,7 +21,6 @@ from .types import (
|
||||
DeepHealthResponse,
|
||||
DeleteAgentResponse,
|
||||
EOR,
|
||||
FreezeAgentResponse,
|
||||
GetAgentResponse,
|
||||
GetEpochResponse,
|
||||
GetExportResponse,
|
||||
@@ -80,7 +81,7 @@ class ElydoraClient:
|
||||
self.private_key = private_key
|
||||
self.base_url = base_url.rstrip("/")
|
||||
self.ttl_ms = ttl_ms
|
||||
self.max_retries = max_retries
|
||||
self.max_retries = require_max_retries(max_retries)
|
||||
self.token = token
|
||||
|
||||
self._prev_chain_hash = GENESIS_CHAIN_HASH
|
||||
@@ -117,33 +118,17 @@ class ElydoraClient:
|
||||
url = f"{self.base_url}{path}"
|
||||
hdrs = headers or self._headers()
|
||||
|
||||
last_exc: Optional[Exception] = None
|
||||
for attempt in range(0, self.max_retries + 1):
|
||||
try:
|
||||
resp = self._session.request(
|
||||
method, url, json=json_body, params=params, headers=hdrs, timeout=30
|
||||
)
|
||||
# Retry on 429 or 5xx
|
||||
if resp.status_code == 429 or resp.status_code >= 500:
|
||||
if attempt < self.max_retries:
|
||||
retry_after = resp.headers.get("Retry-After")
|
||||
if retry_after and retry_after.isdigit():
|
||||
delay = int(retry_after)
|
||||
else:
|
||||
delay = min(2 ** attempt, 8)
|
||||
time.sleep(delay)
|
||||
continue
|
||||
return self._handle_response(resp)
|
||||
except ElydoraError:
|
||||
raise
|
||||
except (requests.exceptions.ConnectionError, requests.exceptions.Timeout) as exc:
|
||||
last_exc = exc
|
||||
if attempt < self.max_retries:
|
||||
time.sleep(min(2 ** attempt, 8))
|
||||
continue
|
||||
raise
|
||||
|
||||
raise last_exc # type: ignore[misc]
|
||||
return request_with_retries(
|
||||
self._session,
|
||||
method,
|
||||
url,
|
||||
path=path,
|
||||
max_retries=self.max_retries,
|
||||
response_handler=self._handle_response,
|
||||
json_body=json_body,
|
||||
params=params,
|
||||
headers=hdrs,
|
||||
)
|
||||
|
||||
@staticmethod
|
||||
def _handle_response(resp: requests.Response) -> Any:
|
||||
|
||||
Reference in new issue
Block a user