Skip to content

Instantly share code, notes, and snippets.

@marcoceppi
Created January 14, 2019 15:35
Show Gist options
  • Save marcoceppi/ff612ee838696999a5154717ad25ea2f to your computer and use it in GitHub Desktop.
Save marcoceppi/ff612ee838696999a5154717ad25ea2f to your computer and use it in GitHub Desktop.
class ExponentialBackoff:
def __init__(self, base=1, integral=False):
self._base = base
self._exp = 0
self._max = 10
self._reset_time = base * 2 ** 11
self._last_invocation = time.monotonic()
r = random.Random()
r.seed()
self._randfunc = r.randrange if integral else r.uniform
def delay(self):
invocation = time.monotonic()
interval = invocation - self._last_invocation
self._last_invocation = invocation
if interval > self._reset_time:
self._exp = 0
self._exp = min(self._exp + 1, self._max)
return self._randfunc(0, self._base * 2 ** self._exp)
backoff = ExponentialBackoff()
while not self.is_closed():
try:
await func()
except (
aiohttp.ClientError,
asyncio.TimeoutError,
websockets.InvalidHandshake,
websockets.WebSocketProtocolError
) as exc:
if not reconnect:
await self.close()
raise
if self.is_closed():
return
retry = backoff.delay()
log.exception("Attempting a reconnect in %.2fs", retry)
await asyncio.sleep(retry, loop=self.loop)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment