Skip to content

Commit 60366d2

Browse files
andreasgudmundssonjeffwidman
authored andcommitted
fix(core): change KazooRetry to uniformly jitter over the whole backoff interval (#521)
The previous implementation would add a fixed amount of jitter around the calculated back-off time. Retry attempts were thus clustered around the exponentially spaced backoff points. This patch does exponential backoff but uniformly spreads the retries over an interval [0, backoff**attempt]
1 parent 35ce106 commit 60366d2

2 files changed

Lines changed: 3 additions & 10 deletions

File tree

kazoo/client.py

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -79,15 +79,13 @@
7979
max_retries=None,
8080
retry_delay=0.1,
8181
retry_backoff=2,
82-
retry_jitter=0.8,
8382
retry_max_delay=3600,
8483
)
8584

8685
_RETRY_COMPAT_MAPPING = dict(
8786
max_retries='max_tries',
8887
retry_delay='delay',
8988
retry_backoff='backoff',
90-
retry_jitter='max_jitter',
9189
retry_max_delay='max_delay',
9290
)
9391

kazoo/retry.py

Lines changed: 3 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -42,19 +42,17 @@ class KazooRetry(object):
4242
SessionExpiredError,
4343
)
4444

45-
def __init__(self, max_tries=1, delay=0.1, backoff=2, max_jitter=0.8,
45+
def __init__(self, max_tries=1, delay=0.1, backoff=2,
4646
max_delay=60, ignore_expire=True, sleep_func=time.sleep,
4747
deadline=None, interrupt=None):
4848
"""Create a :class:`KazooRetry` instance for retrying function
49-
calls
49+
calls with uniform jitter
5050
5151
:param max_tries: How many times to retry the command. -1 means
5252
infinite tries.
5353
:param delay: Initial delay between retry attempts.
5454
:param backoff: Backoff multiplier between retry attempts.
5555
Defaults to 2 for exponential backoff.
56-
:param max_jitter: Additional max jitter period to wait between
57-
retry attempts to avoid slamming the server.
5856
:param max_delay: Maximum delay in seconds, regardless of other
5957
backoff settings. Defaults to one minute.
6058
:param ignore_expire:
@@ -70,7 +68,6 @@ def __init__(self, max_tries=1, delay=0.1, backoff=2, max_jitter=0.8,
7068
self.max_tries = max_tries
7169
self.delay = delay
7270
self.backoff = backoff
73-
self.max_jitter = int(max_jitter * 100)
7471
self.max_delay = float(max_delay)
7572
self._attempts = 0
7673
self._cur_delay = delay
@@ -93,7 +90,6 @@ def copy(self):
9390
obj = KazooRetry(max_tries=self.max_tries,
9491
delay=self.delay,
9592
backoff=self.backoff,
96-
max_jitter=self.max_jitter / 100.0,
9793
max_delay=self.max_delay,
9894
sleep_func=self.sleep_func,
9995
deadline=self.deadline,
@@ -129,8 +125,7 @@ def __call__(self, func, *args, **kwargs):
129125
if self._attempts == self.max_tries:
130126
raise RetryFailedError("Too many retry attempts")
131127
self._attempts += 1
132-
sleeptime = self._cur_delay + (
133-
random.randint(0, self.max_jitter) / 100.0)
128+
sleeptime = random.randint(0, 1 + int(self._cur_delay))
134129

135130
if self._cur_stoptime is not None and \
136131
time.time() + sleeptime >= self._cur_stoptime:

0 commit comments

Comments
 (0)