Coverage for /pythoncovmergedfiles/medio/medio/usr/local/lib/python3.8/site-packages/redis/backoff.py: 53%
51 statements
« prev ^ index » next coverage.py v7.2.7, created at 2023-06-07 07:16 +0000
« prev ^ index » next coverage.py v7.2.7, created at 2023-06-07 07:16 +0000
1import random
2from abc import ABC, abstractmethod
4# Maximum backoff between each retry in seconds
5DEFAULT_CAP = 0.512
6# Minimum backoff between each retry in seconds
7DEFAULT_BASE = 0.008
10class AbstractBackoff(ABC):
11 """Backoff interface"""
13 def reset(self):
14 """
15 Reset internal state before an operation.
16 `reset` is called once at the beginning of
17 every call to `Retry.call_with_retry`
18 """
19 pass
21 @abstractmethod
22 def compute(self, failures):
23 """Compute backoff in seconds upon failure"""
24 pass
27class ConstantBackoff(AbstractBackoff):
28 """Constant backoff upon failure"""
30 def __init__(self, backoff):
31 """`backoff`: backoff time in seconds"""
32 self._backoff = backoff
34 def compute(self, failures):
35 return self._backoff
38class NoBackoff(ConstantBackoff):
39 """No backoff upon failure"""
41 def __init__(self):
42 super().__init__(0)
45class ExponentialBackoff(AbstractBackoff):
46 """Exponential backoff upon failure"""
48 def __init__(self, cap=DEFAULT_CAP, base=DEFAULT_BASE):
49 """
50 `cap`: maximum backoff time in seconds
51 `base`: base backoff time in seconds
52 """
53 self._cap = cap
54 self._base = base
56 def compute(self, failures):
57 return min(self._cap, self._base * 2**failures)
60class FullJitterBackoff(AbstractBackoff):
61 """Full jitter backoff upon failure"""
63 def __init__(self, cap=DEFAULT_CAP, base=DEFAULT_BASE):
64 """
65 `cap`: maximum backoff time in seconds
66 `base`: base backoff time in seconds
67 """
68 self._cap = cap
69 self._base = base
71 def compute(self, failures):
72 return random.uniform(0, min(self._cap, self._base * 2**failures))
75class EqualJitterBackoff(AbstractBackoff):
76 """Equal jitter backoff upon failure"""
78 def __init__(self, cap=DEFAULT_CAP, base=DEFAULT_BASE):
79 """
80 `cap`: maximum backoff time in seconds
81 `base`: base backoff time in seconds
82 """
83 self._cap = cap
84 self._base = base
86 def compute(self, failures):
87 temp = min(self._cap, self._base * 2**failures) / 2
88 return temp + random.uniform(0, temp)
91class DecorrelatedJitterBackoff(AbstractBackoff):
92 """Decorrelated jitter backoff upon failure"""
94 def __init__(self, cap=DEFAULT_CAP, base=DEFAULT_BASE):
95 """
96 `cap`: maximum backoff time in seconds
97 `base`: base backoff time in seconds
98 """
99 self._cap = cap
100 self._base = base
101 self._previous_backoff = 0
103 def reset(self):
104 self._previous_backoff = 0
106 def compute(self, failures):
107 max_backoff = max(self._base, self._previous_backoff * 3)
108 temp = random.uniform(self._base, max_backoff)
109 self._previous_backoff = min(self._cap, temp)
110 return self._previous_backoff
113def default_backoff():
114 return EqualJitterBackoff()