diff options
author | nbraun-amazon <85549956+nbraun-amazon@users.noreply.github.com> | 2021-08-18 12:06:09 +0300 |
---|---|---|
committer | GitHub <noreply@github.com> | 2021-08-18 12:06:09 +0300 |
commit | e19a76c58f2a998d86e51c5a2a0f1db37563efce (patch) | |
tree | 876614bb653f6df4006ab64cece4078d0355f067 /redis/retry.py | |
parent | b96af52e012bc002df97c4a82a5e4ad389cea3f3 (diff) | |
download | redis-py-e19a76c58f2a998d86e51c5a2a0f1db37563efce.tar.gz |
Add retry mechanism with backoff (#1494)
Diffstat (limited to 'redis/retry.py')
-rw-r--r-- | redis/retry.py | 40 |
1 files changed, 40 insertions, 0 deletions
diff --git a/redis/retry.py b/redis/retry.py new file mode 100644 index 0000000..cd06a23 --- /dev/null +++ b/redis/retry.py @@ -0,0 +1,40 @@ +from time import sleep + +from redis.exceptions import ConnectionError, TimeoutError + + +class Retry: + """Retry a specific number of times after a failure""" + + def __init__(self, backoff, retries, + supported_errors=(ConnectionError, TimeoutError)): + """ + Initialize a `Retry` object with a `Backoff` object + that retries a maximum of `retries` times. + You can specify the types of supported errors which trigger + a retry with the `supported_errors` parameter. + """ + self._backoff = backoff + self._retries = retries + self._supported_errors = supported_errors + + def call_with_retry(self, do, fail): + """ + Execute an operation that might fail and returns its result, or + raise the exception that was thrown depending on the `Backoff` object. + `do`: the operation to call. Expects no argument. + `fail`: the failure handler, expects the last error that was thrown + """ + self._backoff.reset() + failures = 0 + while True: + try: + return do() + except self._supported_errors as error: + failures += 1 + fail(error) + if failures > self._retries: + raise error + backoff = self._backoff.compute(failures) + if backoff > 0: + sleep(backoff) |