Skip to content

Commit abd9965

Browse files
authored
Use more defensive checks for ratelimits (#176)
Troi is used in LB radio in production where it can be invoked in an api request context. Multiple api requests modifying the global domain_ratelimit_lookup concurrently causes issues with the ratelimiting logic. For instance, one thread can check that the key exists in the dict but another thread can delete the key from the dict before the first has accessed the key leading to issues. Since, the key is only deleted after the sleep it can be safely ignored by using more defensive accesses.
1 parent e4d6630 commit abd9965

File tree

1 file changed

+9
-6
lines changed

1 file changed

+9
-6
lines changed

troi/http_request.py

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -60,18 +60,21 @@ def http_fetch(url, method, headers=None, params=None, **kwargs):
6060
parse = urlparse(url)
6161
while True:
6262
_key = parse.scheme + parse.netloc
63-
if _key in domain_ratelimit_lookup:
64-
(limit, remaining, reset) = domain_ratelimit_lookup[_key]
63+
ratelimit = domain_ratelimit_lookup.get(_key, None)
64+
if ratelimit is not None:
65+
(limit, remaining, reset) = ratelimit
6566

6667
# MB's rate limit headers are borked, so for the time being, use nearly 1s
6768
if parse.netloc.startswith("musicbrainz.org"):
6869
time_left = .9
6970
else:
7071
time_left = reset - time()
71-
if time_left > 0:
72-
time_to_wait = time_left / remaining
73-
sleep(time_to_wait)
74-
del domain_ratelimit_lookup[_key]
72+
73+
if time_left > 0:
74+
time_to_wait = time_left / remaining
75+
sleep(time_to_wait)
76+
77+
domain_ratelimit_lookup.pop(_key, None)
7578

7679
if method == "GET":
7780
r = session.get(url, params=params, headers=headers, **kwargs)

0 commit comments

Comments
 (0)