Coverage for /pythoncovmergedfiles/medio/medio/usr/local/lib/python3.8/site-packages/botocore/retries/quota.py: 33%
24 statements
« prev ^ index » next coverage.py v7.3.2, created at 2023-12-08 06:51 +0000
« prev ^ index » next coverage.py v7.3.2, created at 2023-12-08 06:51 +0000
1"""Retry quota implementation.
4"""
5import threading
8class RetryQuota:
9 INITIAL_CAPACITY = 500
11 def __init__(self, initial_capacity=INITIAL_CAPACITY, lock=None):
12 self._max_capacity = initial_capacity
13 self._available_capacity = initial_capacity
14 if lock is None:
15 lock = threading.Lock()
16 self._lock = lock
18 def acquire(self, capacity_amount):
19 """Attempt to aquire a certain amount of capacity.
21 If there's not sufficient amount of capacity available, ``False``
22 is returned. Otherwise, ``True`` is returned, which indicates that
23 capacity was successfully allocated.
25 """
26 # The acquire() is only called when we encounter a retryable
27 # response so we aren't worried about locking the entire method.
28 with self._lock:
29 if capacity_amount > self._available_capacity:
30 return False
31 self._available_capacity -= capacity_amount
32 return True
34 def release(self, capacity_amount):
35 """Release capacity back to the retry quota.
37 The capacity being released will be truncated if necessary
38 to ensure the max capacity is never exceeded.
40 """
41 # Implementation note: The release() method is called as part
42 # of the "after-call" event, which means it gets invoked for
43 # every API call. In the common case where the request is
44 # successful and we're at full capacity, we can avoid locking.
45 # We can't exceed max capacity so there's no work we have to do.
46 if self._max_capacity == self._available_capacity:
47 return
48 with self._lock:
49 amount = min(
50 self._max_capacity - self._available_capacity, capacity_amount
51 )
52 self._available_capacity += amount
54 @property
55 def available_capacity(self):
56 return self._available_capacity