Source code for alibabacloud_oss_v2.retry.backoff

"""Modules for backoff """

import abc
import sys
import random
from math import log2

[docs] class BackoffDelayer(abc.ABC): """Abstract base class for backoff delayer."""
[docs] @abc.abstractmethod def backoff_delay(self, attempt: int, error: Exception) -> float: """Returns the delay that should be used before retrying the attempt. Args: attempt (int): current retry attempt error (Exception): the error meets Returns: float: delay duration in second. """
[docs] class FixedDelayBackoff(BackoffDelayer): """FixedDelayBackoff implements fixed backoff.""" def __init__(self, backoff:float) -> None: """ Args: backoff (float): the delay duration in second """ self._backoff = backoff
[docs] def backoff_delay(self, attempt: int, error: Exception) -> float: """Returns the delay that should be used before retrying the attempt. Args: attempt (int): current retry attempt error (Exception): the error meets Returns: float: delay duration in second. """ return self._backoff
def __repr__(self) -> str: return f"<FixedDelayBackoff, backoff: '{self._backoff}'>"
[docs] class FullJitterBackoff(BackoffDelayer): """FullJitterBackoff implements capped exponential backoff with jitter. [0.0, 1.0) * min(2 ^ attempts * baseDealy, maxBackoff) """ def __init__(self, base_delay:float, max_backoff:float) -> None: """ Args: base_delay (float): the base delay duration in second max_backoff (float): the max duration in second """ self._base_delay = base_delay self._max_backoff = max_backoff self._attempt_celling = int(log2(float(sys.maxsize) / base_delay))
[docs] def backoff_delay(self, attempt: int, error: Exception) -> float: """Returns the delay that should be used before retrying the attempt. Args: attempt (int): current retry attempt error (Exception): the error meets Returns: float: delay duration in second. """ attempt = min(attempt, self._attempt_celling) delay = min((self._base_delay * (1 << attempt)), self._max_backoff) rand = random.uniform(0, 1) return rand * delay
def __repr__(self) -> str: return f"<FullJitterBackoff, base delay: '{self._base_delay}', max backoff: '{self._max_backoff}'>"
[docs] class EqualJitterBackoff(BackoffDelayer): """EqualJJitterBackoff implements equal jitter backoff. ceil = min(2 ^ attempts * baseDealy, maxBackoff) ceil/2 + [0.0, 1.0) *(ceil/2 + 1) """ def __init__(self, base_delay:float, max_backoff:float) -> None: """ Args: base_delay (float): the base delay duration in second max_backoff (float): the max duration in second """ self._base_delay = base_delay self._max_backoff = max_backoff self._attempt_celling = int(log2(float(sys.maxsize) / base_delay))
[docs] def backoff_delay(self, attempt: int, error: Exception) -> float: """Returns the delay that should be used before retrying the attempt. Args: attempt (int): current retry attempt error (Exception): the error meets Returns: float: delay duration in second. """ attempt = min(attempt, self._attempt_celling) delay = min((self._base_delay * (1 << attempt)), self._max_backoff) half = delay/2 rand = random.uniform(0, 1) return half + rand * (half + 1)
def __repr__(self) -> str: return f"<EqualJitterBackoff, base delay: '{self._base_delay}', max backoff: '{self._max_backoff}'>"