diff options
author | Kristján Valur Jónsson <sweskman@gmail.com> | 2022-04-28 11:16:14 +0000 |
---|---|---|
committer | GitHub <noreply@github.com> | 2022-04-28 14:16:14 +0300 |
commit | c29d158c854c659994b6d8704d4b420faaa95bca (patch) | |
tree | fe6e5ff9c6d5d611aa907115d8ec5c05581f77d5 | |
parent | abd5aeffc5cca02826973ab32e4d43e200eff18e (diff) | |
download | redis-py-c29d158c854c659994b6d8704d4b420faaa95bca.tar.gz |
`Retry()`: Support negative `retries` value (#2110)
* Support negative `retries` value
* Add unit test
* Add unittest for blocking api
-rw-r--r-- | CHANGES | 1 | ||||
-rw-r--r-- | redis/asyncio/retry.py | 3 | ||||
-rw-r--r-- | redis/retry.py | 3 | ||||
-rw-r--r-- | tests/test_asyncio/test_retry.py | 16 | ||||
-rw-r--r-- | tests/test_retry.py | 15 |
5 files changed, 36 insertions, 2 deletions
@@ -1,4 +1,5 @@ + * Allow negative `retries` for `Retry` class to retry forever * Add `items` parameter to `hset` signature * Create codeql-analysis.yml (#1988). Thanks @chayim * Add limited support for Lua scripting with RedisCluster diff --git a/redis/asyncio/retry.py b/redis/asyncio/retry.py index 284eacc..0934ad0 100644 --- a/redis/asyncio/retry.py +++ b/redis/asyncio/retry.py @@ -27,6 +27,7 @@ class Retry: """ Initialize a `Retry` object with a `Backoff` object that retries a maximum of `retries` times. + `retries` can be negative to retry forever. You can specify the types of supported errors which trigger a retry with the `supported_errors` parameter. """ @@ -51,7 +52,7 @@ class Retry: except self._supported_errors as error: failures += 1 await fail(error) - if failures > self._retries: + if self._retries >= 0 and failures > self._retries: raise error backoff = self._backoff.compute(failures) if backoff > 0: diff --git a/redis/retry.py b/redis/retry.py index 3dced35..57be971 100644 --- a/redis/retry.py +++ b/redis/retry.py @@ -16,6 +16,7 @@ class Retry: """ Initialize a `Retry` object with a `Backoff` object that retries a maximum of `retries` times. + `retries` can be negative to retry forever. You can specify the types of supported errors which trigger a retry with the `supported_errors` parameter. """ @@ -46,7 +47,7 @@ class Retry: except self._supported_errors as error: failures += 1 fail(error) - if failures > self._retries: + if self._retries >= 0 and failures > self._retries: raise error backoff = self._backoff.compute(failures) if backoff > 0: diff --git a/tests/test_asyncio/test_retry.py b/tests/test_asyncio/test_retry.py index e83e001..dee83ba 100644 --- a/tests/test_asyncio/test_retry.py +++ b/tests/test_asyncio/test_retry.py @@ -56,6 +56,11 @@ class TestRetry: async def _fail(self, error): self.actual_failures += 1 + async def _fail_inf(self, error): + self.actual_failures += 1 + if self.actual_failures == 5: + raise ConnectionError() + @pytest.mark.parametrize("retries", range(10)) @pytest.mark.asyncio async def test_retry(self, retries: int): @@ -68,3 +73,14 @@ class TestRetry: assert self.actual_failures == 1 + retries assert backoff.reset_calls == 1 assert backoff.calls == retries + + @pytest.mark.asyncio + async def test_infinite_retry(self): + backoff = BackoffMock() + # specify infinite retries, but give up after 5 + retry = Retry(backoff, -1) + with pytest.raises(ConnectionError): + await retry.call_with_retry(self._do, self._fail_inf) + + assert self.actual_attempts == 5 + assert self.actual_failures == 5 diff --git a/tests/test_retry.py b/tests/test_retry.py index 0094787..f844fd0 100644 --- a/tests/test_retry.py +++ b/tests/test_retry.py @@ -95,6 +95,11 @@ class TestRetry: def _fail(self, error): self.actual_failures += 1 + def _fail_inf(self, error): + self.actual_failures += 1 + if self.actual_failures == 5: + raise ConnectionError() + @pytest.mark.parametrize("retries", range(10)) def test_retry(self, retries): backoff = BackoffMock() @@ -107,6 +112,16 @@ class TestRetry: assert backoff.reset_calls == 1 assert backoff.calls == retries + def test_infinite_retry(self): + backoff = BackoffMock() + # specify infinite retries, but give up after 5 + retry = Retry(backoff, -1) + with pytest.raises(ConnectionError): + retry.call_with_retry(self._do, self._fail_inf) + + assert self.actual_attempts == 5 + assert self.actual_failures == 5 + @pytest.mark.onlynoncluster class TestRedisClientRetry: |