diff --git a/src/sumo/wrapper/_blob_client.py b/src/sumo/wrapper/_blob_client.py index e1134e9..45c4128 100644 --- a/src/sumo/wrapper/_blob_client.py +++ b/src/sumo/wrapper/_blob_client.py @@ -1,7 +1,7 @@ import httpx -from ._decorators import is_retryable_exception, is_retryable_status_code, raise_for_status, raise_for_status_async -from tenacity import retry, retry_if_exception, retry_if_result, wait_exponential_jitter, stop_after_attempt +from ._decorators import is_retryable_exception, is_retryable_status_code, raise_for_status, raise_for_status_async, return_last_value +from tenacity import retry, retry_if_exception, retry_if_result, wait_exponential, wait_random_exponential, stop_after_attempt class BlobClient: """Upload blobs to blob store using pre-authorized URLs""" @@ -12,8 +12,9 @@ class BlobClient: retry_if_exception(is_retryable_exception) | retry_if_result(is_retryable_status_code) ), - wait=wait_exponential_jitter(), + wait=wait_exponential(multiplier=0.5)+wait_random_exponential(multiplier=0.5), reraise=True, + retry_error_callback=return_last_value, ) def upload_blob(self, blob: bytes, url: str): """Upload a blob. @@ -38,8 +39,9 @@ def upload_blob(self, blob: bytes, url: str): retry_if_exception(is_retryable_exception) | retry_if_result(is_retryable_status_code) ), - wait=wait_exponential_jitter(), + wait=wait_exponential(multiplier=0.5)+wait_random_exponential(multiplier=0.5), reraise=True, + retry_error_callback=return_last_value, ) async def upload_blob_async(self, blob: bytes, url: str): """Upload a blob async. diff --git a/src/sumo/wrapper/_decorators.py b/src/sumo/wrapper/_decorators.py index a2c52cc..2c11451 100644 --- a/src/sumo/wrapper/_decorators.py +++ b/src/sumo/wrapper/_decorators.py @@ -50,6 +50,10 @@ def is_retryable_status_code(response): return response.status_code in [502, 503, 504] +def return_last_value(retry_state): + return retry_state.outcome.result() + + def http_retry(func): return tn.retry( func, diff --git a/src/sumo/wrapper/sumo_client.py b/src/sumo/wrapper/sumo_client.py index f0d3140..ae374c9 100644 --- a/src/sumo/wrapper/sumo_client.py +++ b/src/sumo/wrapper/sumo_client.py @@ -10,9 +10,9 @@ from .config import APP_REGISTRATION, TENANT_ID, AUTHORITY_HOST_URI from ._decorators import is_retryable_exception, \ - is_retryable_status_code, raise_for_status, raise_for_status_async + is_retryable_status_code, raise_for_status, raise_for_status_async, return_last_value from tenacity import retry, retry_if_exception, retry_if_result, \ - wait_exponential_jitter, stop_after_attempt + wait_exponential, wait_random_exponential, stop_after_attempt logger = logging.getLogger("sumo.wrapper") @@ -117,8 +117,9 @@ def blob_client(self) -> BlobClient: retry_if_exception(is_retryable_exception) | retry_if_result(is_retryable_status_code) ), - wait=wait_exponential_jitter(), + wait=wait_exponential(multiplier=0.5)+wait_random_exponential(multiplier=0.5), reraise=True, + retry_error_callback=return_last_value, ) def get(self, path: str, params: dict = None) -> dict: """Performs a GET-request to the Sumo API. @@ -171,8 +172,9 @@ def get(self, path: str, params: dict = None) -> dict: retry_if_exception(is_retryable_exception) | retry_if_result(is_retryable_status_code) ), - wait=wait_exponential_jitter(), + wait=wait_exponential(multiplier=0.5)+wait_random_exponential(multiplier=0.5), reraise=True, + retry_error_callback=return_last_value, ) def post( self, @@ -251,8 +253,9 @@ def post( retry_if_exception(is_retryable_exception) | retry_if_result(is_retryable_status_code) ), - wait=wait_exponential_jitter(), + wait=wait_exponential(multiplier=0.5)+wait_random_exponential(multiplier=0.5), reraise=True, + retry_error_callback=return_last_value, ) def put( self, path: str, blob: bytes = None, json: dict = None @@ -303,8 +306,9 @@ def put( retry_if_exception(is_retryable_exception) | retry_if_result(is_retryable_status_code) ), - wait=wait_exponential_jitter(), + wait=wait_exponential(multiplier=0.5)+wait_random_exponential(multiplier=0.5), reraise=True, + retry_error_callback=return_last_value, ) def delete(self, path: str, params: dict = None) -> dict: """Performs a DELETE-request to the Sumo API. @@ -365,8 +369,9 @@ def getLogger(self, name): retry_if_exception(is_retryable_exception) | retry_if_result(is_retryable_status_code) ), - wait=wait_exponential_jitter(), + wait=wait_exponential(multiplier=0.5)+wait_random_exponential(multiplier=0.5), reraise=True, + retry_error_callback=return_last_value, ) async def get_async(self, path: str, params: dict = None): """Performs an async GET-request to the Sumo API. @@ -418,8 +423,9 @@ async def get_async(self, path: str, params: dict = None): retry_if_exception(is_retryable_exception) | retry_if_result(is_retryable_status_code) ), - wait=wait_exponential_jitter(), + wait=wait_exponential(multiplier=0.5)+wait_random_exponential(multiplier=0.5), reraise=True, + retry_error_callback=return_last_value, ) async def post_async( self, @@ -501,8 +507,9 @@ async def post_async( retry_if_exception(is_retryable_exception) | retry_if_result(is_retryable_status_code) ), - wait=wait_exponential_jitter(), + wait=wait_exponential(multiplier=0.5)+wait_random_exponential(multiplier=0.5), reraise=True, + retry_error_callback=return_last_value, ) async def put_async( self, path: str, blob: bytes = None, json: dict = None @@ -554,8 +561,9 @@ async def put_async( retry_if_exception(is_retryable_exception) | retry_if_result(is_retryable_status_code) ), - wait=wait_exponential_jitter(), + wait=wait_exponential(multiplier=0.5)+wait_random_exponential(multiplier=0.5), reraise=True, + retry_error_callback=return_last_value, ) async def delete_async(self, path: str, params: dict = None) -> dict: """Performs an async DELETE-request to the Sumo API.