summaryrefslogtreecommitdiff
path: root/redis/retry.py
diff options
context:
space:
mode:
authornbraun-amazon <85549956+nbraun-amazon@users.noreply.github.com>2021-08-18 12:06:09 +0300
committerGitHub <noreply@github.com>2021-08-18 12:06:09 +0300
commite19a76c58f2a998d86e51c5a2a0f1db37563efce (patch)
tree876614bb653f6df4006ab64cece4078d0355f067 /redis/retry.py
parentb96af52e012bc002df97c4a82a5e4ad389cea3f3 (diff)
downloadredis-py-e19a76c58f2a998d86e51c5a2a0f1db37563efce.tar.gz
Add retry mechanism with backoff (#1494)
Diffstat (limited to 'redis/retry.py')
-rw-r--r--redis/retry.py40
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)