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

33 statements  

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) 

13 

14from redis.exceptions import ConnectionError, RedisError, TimeoutError 

15from redis.retry import AbstractRetry 

16 

17T = TypeVar("T") 

18 

19if TYPE_CHECKING: 

20 from redis.backoff import AbstractBackoff 

21 

22 

23class Retry(AbstractRetry[RedisError]): 

24 __hash__ = AbstractRetry.__hash__ 

25 

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) 

36 

37 def __eq__(self, other: Any) -> bool: 

38 if not isinstance(other, Retry): 

39 return NotImplemented 

40 

41 return ( 

42 self._backoff == other._backoff 

43 and self._retries == other._retries 

44 and set(self._supported_errors) == set(other._supported_errors) 

45 ) 

46 

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 

74 

75 if with_failure_count: 

76 await fail(error, failures) 

77 else: 

78 await fail(error) 

79 

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)