Coverage for /pythoncovmergedfiles/medio/medio/usr/local/lib/python3.8/site-packages/redis/asyncio/retry.py: 37%
27 statements
« prev ^ index » next coverage.py v7.4.4, created at 2024-04-23 06:16 +0000
« prev ^ index » next coverage.py v7.4.4, created at 2024-04-23 06:16 +0000
1from asyncio import sleep
2from typing import TYPE_CHECKING, Any, Awaitable, Callable, Tuple, Type, TypeVar
4from redis.exceptions import ConnectionError, RedisError, TimeoutError
6if TYPE_CHECKING:
7 from redis.backoff import AbstractBackoff
10T = TypeVar("T")
13class Retry:
14 """Retry a specific number of times after a failure"""
16 __slots__ = "_backoff", "_retries", "_supported_errors"
18 def __init__(
19 self,
20 backoff: "AbstractBackoff",
21 retries: int,
22 supported_errors: Tuple[Type[RedisError], ...] = (
23 ConnectionError,
24 TimeoutError,
25 ),
26 ):
27 """
28 Initialize a `Retry` object with a `Backoff` object
29 that retries a maximum of `retries` times.
30 `retries` can be negative to retry forever.
31 You can specify the types of supported errors which trigger
32 a retry with the `supported_errors` parameter.
33 """
34 self._backoff = backoff
35 self._retries = retries
36 self._supported_errors = supported_errors
38 def update_supported_errors(self, specified_errors: list):
39 """
40 Updates the supported errors with the specified error types
41 """
42 self._supported_errors = tuple(
43 set(self._supported_errors + tuple(specified_errors))
44 )
46 async def call_with_retry(
47 self, do: Callable[[], Awaitable[T]], fail: Callable[[RedisError], Any]
48 ) -> T:
49 """
50 Execute an operation that might fail and returns its result, or
51 raise the exception that was thrown depending on the `Backoff` object.
52 `do`: the operation to call. Expects no argument.
53 `fail`: the failure handler, expects the last error that was thrown
54 """
55 self._backoff.reset()
56 failures = 0
57 while True:
58 try:
59 return await do()
60 except self._supported_errors as error:
61 failures += 1
62 await fail(error)
63 if self._retries >= 0 and failures > self._retries:
64 raise error
65 backoff = self._backoff.compute(failures)
66 if backoff > 0:
67 await sleep(backoff)