This commit is contained in:
@@ -19,7 +19,7 @@ class AbstractBackoff(ABC):
|
||||
pass
|
||||
|
||||
@abstractmethod
|
||||
def compute(self, failures: int) -> float:
|
||||
def compute(self, failures):
|
||||
"""Compute backoff in seconds upon failure"""
|
||||
pass
|
||||
|
||||
@@ -27,34 +27,25 @@ class AbstractBackoff(ABC):
|
||||
class ConstantBackoff(AbstractBackoff):
|
||||
"""Constant backoff upon failure"""
|
||||
|
||||
def __init__(self, backoff: float) -> None:
|
||||
def __init__(self, backoff):
|
||||
"""`backoff`: backoff time in seconds"""
|
||||
self._backoff = backoff
|
||||
|
||||
def __hash__(self) -> int:
|
||||
return hash((self._backoff,))
|
||||
|
||||
def __eq__(self, other) -> bool:
|
||||
if not isinstance(other, ConstantBackoff):
|
||||
return NotImplemented
|
||||
|
||||
return self._backoff == other._backoff
|
||||
|
||||
def compute(self, failures: int) -> float:
|
||||
def compute(self, failures):
|
||||
return self._backoff
|
||||
|
||||
|
||||
class NoBackoff(ConstantBackoff):
|
||||
"""No backoff upon failure"""
|
||||
|
||||
def __init__(self) -> None:
|
||||
def __init__(self):
|
||||
super().__init__(0)
|
||||
|
||||
|
||||
class ExponentialBackoff(AbstractBackoff):
|
||||
"""Exponential backoff upon failure"""
|
||||
|
||||
def __init__(self, cap: float = DEFAULT_CAP, base: float = DEFAULT_BASE):
|
||||
def __init__(self, cap=DEFAULT_CAP, base=DEFAULT_BASE):
|
||||
"""
|
||||
`cap`: maximum backoff time in seconds
|
||||
`base`: base backoff time in seconds
|
||||
@@ -62,23 +53,14 @@ class ExponentialBackoff(AbstractBackoff):
|
||||
self._cap = cap
|
||||
self._base = base
|
||||
|
||||
def __hash__(self) -> int:
|
||||
return hash((self._base, self._cap))
|
||||
|
||||
def __eq__(self, other) -> bool:
|
||||
if not isinstance(other, ExponentialBackoff):
|
||||
return NotImplemented
|
||||
|
||||
return self._base == other._base and self._cap == other._cap
|
||||
|
||||
def compute(self, failures: int) -> float:
|
||||
def compute(self, failures):
|
||||
return min(self._cap, self._base * 2**failures)
|
||||
|
||||
|
||||
class FullJitterBackoff(AbstractBackoff):
|
||||
"""Full jitter backoff upon failure"""
|
||||
|
||||
def __init__(self, cap: float = DEFAULT_CAP, base: float = DEFAULT_BASE) -> None:
|
||||
def __init__(self, cap=DEFAULT_CAP, base=DEFAULT_BASE):
|
||||
"""
|
||||
`cap`: maximum backoff time in seconds
|
||||
`base`: base backoff time in seconds
|
||||
@@ -86,23 +68,14 @@ class FullJitterBackoff(AbstractBackoff):
|
||||
self._cap = cap
|
||||
self._base = base
|
||||
|
||||
def __hash__(self) -> int:
|
||||
return hash((self._base, self._cap))
|
||||
|
||||
def __eq__(self, other) -> bool:
|
||||
if not isinstance(other, FullJitterBackoff):
|
||||
return NotImplemented
|
||||
|
||||
return self._base == other._base and self._cap == other._cap
|
||||
|
||||
def compute(self, failures: int) -> float:
|
||||
def compute(self, failures):
|
||||
return random.uniform(0, min(self._cap, self._base * 2**failures))
|
||||
|
||||
|
||||
class EqualJitterBackoff(AbstractBackoff):
|
||||
"""Equal jitter backoff upon failure"""
|
||||
|
||||
def __init__(self, cap: float = DEFAULT_CAP, base: float = DEFAULT_BASE) -> None:
|
||||
def __init__(self, cap=DEFAULT_CAP, base=DEFAULT_BASE):
|
||||
"""
|
||||
`cap`: maximum backoff time in seconds
|
||||
`base`: base backoff time in seconds
|
||||
@@ -110,16 +83,7 @@ class EqualJitterBackoff(AbstractBackoff):
|
||||
self._cap = cap
|
||||
self._base = base
|
||||
|
||||
def __hash__(self) -> int:
|
||||
return hash((self._base, self._cap))
|
||||
|
||||
def __eq__(self, other) -> bool:
|
||||
if not isinstance(other, EqualJitterBackoff):
|
||||
return NotImplemented
|
||||
|
||||
return self._base == other._base and self._cap == other._cap
|
||||
|
||||
def compute(self, failures: int) -> float:
|
||||
def compute(self, failures):
|
||||
temp = min(self._cap, self._base * 2**failures) / 2
|
||||
return temp + random.uniform(0, temp)
|
||||
|
||||
@@ -127,7 +91,7 @@ class EqualJitterBackoff(AbstractBackoff):
|
||||
class DecorrelatedJitterBackoff(AbstractBackoff):
|
||||
"""Decorrelated jitter backoff upon failure"""
|
||||
|
||||
def __init__(self, cap: float = DEFAULT_CAP, base: float = DEFAULT_BASE) -> None:
|
||||
def __init__(self, cap=DEFAULT_CAP, base=DEFAULT_BASE):
|
||||
"""
|
||||
`cap`: maximum backoff time in seconds
|
||||
`base`: base backoff time in seconds
|
||||
@@ -136,48 +100,15 @@ class DecorrelatedJitterBackoff(AbstractBackoff):
|
||||
self._base = base
|
||||
self._previous_backoff = 0
|
||||
|
||||
def __hash__(self) -> int:
|
||||
return hash((self._base, self._cap))
|
||||
|
||||
def __eq__(self, other) -> bool:
|
||||
if not isinstance(other, DecorrelatedJitterBackoff):
|
||||
return NotImplemented
|
||||
|
||||
return self._base == other._base and self._cap == other._cap
|
||||
|
||||
def reset(self) -> None:
|
||||
def reset(self):
|
||||
self._previous_backoff = 0
|
||||
|
||||
def compute(self, failures: int) -> float:
|
||||
def compute(self, failures):
|
||||
max_backoff = max(self._base, self._previous_backoff * 3)
|
||||
temp = random.uniform(self._base, max_backoff)
|
||||
self._previous_backoff = min(self._cap, temp)
|
||||
return self._previous_backoff
|
||||
|
||||
|
||||
class ExponentialWithJitterBackoff(AbstractBackoff):
|
||||
"""Exponential backoff upon failure, with jitter"""
|
||||
|
||||
def __init__(self, cap: float = DEFAULT_CAP, base: float = DEFAULT_BASE) -> None:
|
||||
"""
|
||||
`cap`: maximum backoff time in seconds
|
||||
`base`: base backoff time in seconds
|
||||
"""
|
||||
self._cap = cap
|
||||
self._base = base
|
||||
|
||||
def __hash__(self) -> int:
|
||||
return hash((self._base, self._cap))
|
||||
|
||||
def __eq__(self, other) -> bool:
|
||||
if not isinstance(other, ExponentialWithJitterBackoff):
|
||||
return NotImplemented
|
||||
|
||||
return self._base == other._base and self._cap == other._cap
|
||||
|
||||
def compute(self, failures: int) -> float:
|
||||
return min(self._cap, random.random() * self._base * 2**failures)
|
||||
|
||||
|
||||
def default_backoff():
|
||||
return EqualJitterBackoff()
|
||||
|
||||
Reference in New Issue
Block a user