Coverage for /pythoncovmergedfiles/medio/medio/usr/local/lib/python3.8/site-packages/google/auth/_exponential_backoff.py: 44%
34 statements
« prev ^ index » next coverage.py v7.2.7, created at 2023-06-06 06:03 +0000
« prev ^ index » next coverage.py v7.2.7, created at 2023-06-06 06:03 +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.
15import random
16import time
18import six
20# The default amount of retry attempts
21_DEFAULT_RETRY_TOTAL_ATTEMPTS = 3
23# The default initial backoff period (1.0 second).
24_DEFAULT_INITIAL_INTERVAL_SECONDS = 1.0
26# The default randomization factor (0.1 which results in a random period ranging
27# between 10% below and 10% above the retry interval).
28_DEFAULT_RANDOMIZATION_FACTOR = 0.1
30# The default multiplier value (2 which is 100% increase per back off).
31_DEFAULT_MULTIPLIER = 2.0
33"""Exponential Backoff Utility
35This is a private module that implements the exponential back off algorithm.
36It can be used as a utility for code that needs to retry on failure, for example
37an HTTP request.
38"""
41class ExponentialBackoff(six.Iterator):
42 """An exponential backoff iterator. This can be used in a for loop to
43 perform requests with exponential backoff.
45 Args:
46 total_attempts Optional[int]:
47 The maximum amount of retries that should happen.
48 The default value is 3 attempts.
49 initial_wait_seconds Optional[int]:
50 The amount of time to sleep in the first backoff. This parameter
51 should be in seconds.
52 The default value is 1 second.
53 randomization_factor Optional[float]:
54 The amount of jitter that should be in each backoff. For example,
55 a value of 0.1 will introduce a jitter range of 10% to the
56 current backoff period.
57 The default value is 0.1.
58 multiplier Optional[float]:
59 The backoff multipler. This adjusts how much each backoff will
60 increase. For example a value of 2.0 leads to a 200% backoff
61 on each attempt. If the initial_wait is 1.0 it would look like
62 this sequence [1.0, 2.0, 4.0, 8.0].
63 The default value is 2.0.
64 """
66 def __init__(
67 self,
68 total_attempts=_DEFAULT_RETRY_TOTAL_ATTEMPTS,
69 initial_wait_seconds=_DEFAULT_INITIAL_INTERVAL_SECONDS,
70 randomization_factor=_DEFAULT_RANDOMIZATION_FACTOR,
71 multiplier=_DEFAULT_MULTIPLIER,
72 ):
73 self._total_attempts = total_attempts
74 self._initial_wait_seconds = initial_wait_seconds
76 self._current_wait_in_seconds = self._initial_wait_seconds
78 self._randomization_factor = randomization_factor
79 self._multiplier = multiplier
80 self._backoff_count = 0
82 def __iter__(self):
83 self._backoff_count = 0
84 self._current_wait_in_seconds = self._initial_wait_seconds
85 return self
87 def __next__(self):
88 if self._backoff_count >= self._total_attempts:
89 raise StopIteration
90 self._backoff_count += 1
92 jitter_variance = self._current_wait_in_seconds * self._randomization_factor
93 jitter = random.uniform(
94 self._current_wait_in_seconds - jitter_variance,
95 self._current_wait_in_seconds + jitter_variance,
96 )
98 time.sleep(jitter)
100 self._current_wait_in_seconds *= self._multiplier
101 return self._backoff_count
103 @property
104 def total_attempts(self):
105 """The total amount of backoff attempts that will be made."""
106 return self._total_attempts
108 @property
109 def backoff_count(self):
110 """The current amount of backoff attempts that have been made."""
111 return self._backoff_count