Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 3b6606c

Browse files
committed
Change bidi._Throttle signature
The commit renames the entry_cap parameter to access_limit, and changes the type of the time_window argument from float to timedelta.
1 parent 9c9a10b commit 3b6606c

File tree

2 files changed

+41
-25
lines changed

2 files changed

+41
-25
lines changed

api_core/google/api_core/bidi.py

Lines changed: 23 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -140,8 +140,8 @@ def __iter__(self):
140140
class _Throttle(object):
141141
"""A context manager limiting the total entries in a sliding time window.
142142
143-
If more than ``entry_cap`` attempts are made to enter the context manager
144-
instance in the last ``time window`` seconds, the exceeding requests block
143+
If more than ``access_limit`` attempts are made to enter the context manager
144+
instance in the last ``time window`` interval, the exceeding requests block
145145
until enough time elapses.
146146
147147
The context manager instances are thread-safe and can be shared between
@@ -150,27 +150,29 @@ class _Throttle(object):
150150
151151
Example::
152152
153-
max_three_per_second = Throttle(time_window=1, entry_cap=3)
153+
max_three_per_second = _Throttle(
154+
access_limit=3, time_window=datetime.timedelta(seconds=1)
155+
)
154156
155157
for i in range(5):
156158
with max_three_per_second as time_waited:
157159
print("{}: Waited {} seconds to enter".format(i, time_waited))
158160
159161
Args:
160-
time_window (float): the width of the sliding time window in seconds
161-
entry_cap (int): the maximum number of entries allowed in the time window
162+
access_limit (int): the maximum number of entries allowed in the time window
163+
time_window (datetime.timedelta): the width of the sliding time window
162164
"""
163165

164-
def __init__(self, time_window, entry_cap):
165-
if time_window <= 0.0:
166-
raise ValueError("time_window argument must be positive")
166+
def __init__(self, access_limit, time_window):
167+
if access_limit < 1:
168+
raise ValueError("access_limit argument must be positive")
167169

168-
if entry_cap < 1:
169-
raise ValueError("entry_cap argument must be positive")
170+
if time_window <= datetime.timedelta(0):
171+
raise ValueError("time_window argument must be a positive timedelta")
170172

171-
self._time_window = datetime.timedelta(seconds=time_window)
172-
self._entry_cap = entry_cap
173-
self._past_entries = collections.deque(maxlen=entry_cap) # least recent first
173+
self._time_window = time_window
174+
self._access_limit = access_limit
175+
self._past_entries = collections.deque(maxlen=access_limit) # least recent first
174176
self._entry_lock = threading.Lock()
175177

176178
def __enter__(self):
@@ -181,7 +183,7 @@ def __enter__(self):
181183
while self._past_entries and self._past_entries[0] < cutoff_time:
182184
self._past_entries.popleft()
183185

184-
if len(self._past_entries) < self._entry_cap:
186+
if len(self._past_entries) < self._access_limit:
185187
self._past_entries.append(datetime.datetime.now())
186188
return 0.0 # no waiting was needed
187189

@@ -195,8 +197,10 @@ def __exit__(self, *_):
195197
pass
196198

197199
def __repr__(self):
198-
return "{}(time_window={}, entry_cap={})".format(
199-
self.__class__.__name__, self._time_window.total_seconds(), self._entry_cap
200+
return "{}(access_limit={}, time_window={})".format(
201+
self.__class__.__name__,
202+
self._access_limit,
203+
repr(self._time_window),
200204
)
201205

202206

@@ -408,7 +412,9 @@ def __init__(
408412
self._finalize_lock = threading.Lock()
409413

410414
if throttle_reopen:
411-
self._reopen_throttle = _Throttle(entry_cap=5, time_window=10)
415+
self._reopen_throttle = _Throttle(
416+
access_limit=5, time_window=datetime.timedelta(seconds=10),
417+
)
412418
else:
413419
self._reopen_throttle = None
414420

api_core/tests/unit/test_bidi.py

Lines changed: 18 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -119,22 +119,30 @@ def test_exit_with_stop(self):
119119

120120
class Test_Throttle(object):
121121
def test_repr(self):
122-
instance = bidi._Throttle(time_window=4.5, entry_cap=42)
123-
assert repr(instance) == "_Throttle(time_window=4.5, entry_cap=42)"
122+
delta = datetime.timedelta(seconds=4.5)
123+
instance = bidi._Throttle(access_limit=42, time_window=delta)
124+
assert repr(instance) == \
125+
"_Throttle(access_limit=42, time_window={})".format(repr(delta))
124126

125127
def test_raises_error_on_invalid_init_arguments(self):
126128
with pytest.raises(ValueError) as exc_info:
127-
bidi._Throttle(time_window=0.0, entry_cap=10)
129+
bidi._Throttle(
130+
access_limit=10, time_window=datetime.timedelta(seconds=0.0)
131+
)
128132
assert "time_window" in str(exc_info.value)
129-
assert "must be positive" in str(exc_info.value)
133+
assert "must be a positive timedelta" in str(exc_info.value)
130134

131135
with pytest.raises(ValueError) as exc_info:
132-
bidi._Throttle(time_window=10, entry_cap=0)
133-
assert "entry_cap" in str(exc_info.value)
136+
bidi._Throttle(
137+
access_limit=0, time_window=datetime.timedelta(seconds=10)
138+
)
139+
assert "access_limit" in str(exc_info.value)
134140
assert "must be positive" in str(exc_info.value)
135141

136142
def test_does_not_delay_entry_attempts_under_threshold(self):
137-
throttle = bidi._Throttle(time_window=1, entry_cap=3)
143+
throttle = bidi._Throttle(
144+
access_limit=3, time_window=datetime.timedelta(seconds=1)
145+
)
138146
entries = []
139147

140148
for _ in range(3):
@@ -155,7 +163,9 @@ def test_does_not_delay_entry_attempts_under_threshold(self):
155163
assert delta.total_seconds() < 0.1
156164

157165
def test_delays_entry_attempts_above_threshold(self):
158-
throttle = bidi._Throttle(time_window=1, entry_cap=3)
166+
throttle = bidi._Throttle(
167+
access_limit=3, time_window=datetime.timedelta(seconds=1)
168+
)
159169
entries = []
160170

161171
for _ in range(6):

0 commit comments

Comments
 (0)