Coverage for /pythoncovmergedfiles/medio/medio/usr/local/lib/python3.8/site-packages/google/auth/_exponential_backoff.py: 42%

33 statements  

« prev     ^ index     » next       coverage.py v7.3.2, created at 2023-12-08 06:40 +0000

1# Copyright 2022 Google LLC 

2# 

3# Licensed under the Apache License, Version 2.0 (the "License"); 

4# you may not use this file except in compliance with the License. 

5# You may obtain a copy of the License at 

6# 

7# http://www.apache.org/licenses/LICENSE-2.0 

8# 

9# Unless required by applicable law or agreed to in writing, software 

10# distributed under the License is distributed on an "AS IS" BASIS, 

11# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 

12# See the License for the specific language governing permissions and 

13# limitations under the License. 

14 

15import random 

16import time 

17 

18# The default amount of retry attempts 

19_DEFAULT_RETRY_TOTAL_ATTEMPTS = 3 

20 

21# The default initial backoff period (1.0 second). 

22_DEFAULT_INITIAL_INTERVAL_SECONDS = 1.0 

23 

24# The default randomization factor (0.1 which results in a random period ranging 

25# between 10% below and 10% above the retry interval). 

26_DEFAULT_RANDOMIZATION_FACTOR = 0.1 

27 

28# The default multiplier value (2 which is 100% increase per back off). 

29_DEFAULT_MULTIPLIER = 2.0 

30 

31"""Exponential Backoff Utility 

32 

33This is a private module that implements the exponential back off algorithm. 

34It can be used as a utility for code that needs to retry on failure, for example 

35an HTTP request. 

36""" 

37 

38 

39class ExponentialBackoff: 

40 """An exponential backoff iterator. This can be used in a for loop to 

41 perform requests with exponential backoff. 

42 

43 Args: 

44 total_attempts Optional[int]: 

45 The maximum amount of retries that should happen. 

46 The default value is 3 attempts. 

47 initial_wait_seconds Optional[int]: 

48 The amount of time to sleep in the first backoff. This parameter 

49 should be in seconds. 

50 The default value is 1 second. 

51 randomization_factor Optional[float]: 

52 The amount of jitter that should be in each backoff. For example, 

53 a value of 0.1 will introduce a jitter range of 10% to the 

54 current backoff period. 

55 The default value is 0.1. 

56 multiplier Optional[float]: 

57 The backoff multipler. This adjusts how much each backoff will 

58 increase. For example a value of 2.0 leads to a 200% backoff 

59 on each attempt. If the initial_wait is 1.0 it would look like 

60 this sequence [1.0, 2.0, 4.0, 8.0]. 

61 The default value is 2.0. 

62 """ 

63 

64 def __init__( 

65 self, 

66 total_attempts=_DEFAULT_RETRY_TOTAL_ATTEMPTS, 

67 initial_wait_seconds=_DEFAULT_INITIAL_INTERVAL_SECONDS, 

68 randomization_factor=_DEFAULT_RANDOMIZATION_FACTOR, 

69 multiplier=_DEFAULT_MULTIPLIER, 

70 ): 

71 self._total_attempts = total_attempts 

72 self._initial_wait_seconds = initial_wait_seconds 

73 

74 self._current_wait_in_seconds = self._initial_wait_seconds 

75 

76 self._randomization_factor = randomization_factor 

77 self._multiplier = multiplier 

78 self._backoff_count = 0 

79 

80 def __iter__(self): 

81 self._backoff_count = 0 

82 self._current_wait_in_seconds = self._initial_wait_seconds 

83 return self 

84 

85 def __next__(self): 

86 if self._backoff_count >= self._total_attempts: 

87 raise StopIteration 

88 self._backoff_count += 1 

89 

90 jitter_variance = self._current_wait_in_seconds * self._randomization_factor 

91 jitter = random.uniform( 

92 self._current_wait_in_seconds - jitter_variance, 

93 self._current_wait_in_seconds + jitter_variance, 

94 ) 

95 

96 time.sleep(jitter) 

97 

98 self._current_wait_in_seconds *= self._multiplier 

99 return self._backoff_count 

100 

101 @property 

102 def total_attempts(self): 

103 """The total amount of backoff attempts that will be made.""" 

104 return self._total_attempts 

105 

106 @property 

107 def backoff_count(self): 

108 """The current amount of backoff attempts that have been made.""" 

109 return self._backoff_count