Coverage for /pythoncovmergedfiles/medio/medio/usr/local/lib/python3.11/site-packages/redis/asyncio/retry.py: 36%
Shortcuts on this page
r m x toggle line displays
j k next/prev highlighted chunk
0 (zero) top of page
1 (one) first highlighted chunk
Shortcuts on this page
r m x toggle line displays
j k next/prev highlighted chunk
0 (zero) top of page
1 (one) first highlighted chunk
1from asyncio import sleep
2from typing import (
3 TYPE_CHECKING,
4 Any,
5 Awaitable,
6 Callable,
7 Optional,
8 Tuple,
9 Type,
10 TypeVar,
11 Union,
12)
14from redis.exceptions import ConnectionError, RedisError, TimeoutError
15from redis.retry import AbstractRetry
17T = TypeVar("T")
19if TYPE_CHECKING:
20 from redis.backoff import AbstractBackoff
23class Retry(AbstractRetry[RedisError]):
24 __hash__ = AbstractRetry.__hash__
26 def __init__(
27 self,
28 backoff: "AbstractBackoff",
29 retries: int,
30 supported_errors: Tuple[Type[RedisError], ...] = (
31 ConnectionError,
32 TimeoutError,
33 ),
34 ):
35 super().__init__(backoff, retries, supported_errors)
37 def __eq__(self, other: Any) -> bool:
38 if not isinstance(other, Retry):
39 return NotImplemented
41 return (
42 self._backoff == other._backoff
43 and self._retries == other._retries
44 and set(self._supported_errors) == set(other._supported_errors)
45 )
47 async def call_with_retry(
48 self,
49 do: Callable[[], Awaitable[T]],
50 fail: Union[
51 Callable[[Exception], Any],
52 Callable[[Exception, int], Any],
53 ],
54 is_retryable: Optional[Callable[[Exception], bool]] = None,
55 with_failure_count: bool = False,
56 ) -> T:
57 """
58 Execute an operation that might fail and returns its result, or
59 raise the exception that was thrown depending on the `Backoff` object.
60 `do`: the operation to call. Expects no argument.
61 `fail`: the failure handler, expects the last error that was thrown
62 ``is_retryable``: optional function to determine if an error is retryable
63 ``with_failure_count``: if True, the failure count is passed to the failure handler
64 """
65 self._backoff.reset()
66 failures = 0
67 while True:
68 try:
69 return await do()
70 except self._supported_errors as error:
71 if is_retryable and not is_retryable(error):
72 raise
73 failures += 1
75 if with_failure_count:
76 await fail(error, failures)
77 else:
78 await fail(error)
80 if self._retries >= 0 and failures > self._retries:
81 raise error
82 backoff = self._backoff.compute(failures)
83 if backoff > 0:
84 await sleep(backoff)