diff --git a/README.rst b/README.rst index 5fc9551..a03630d 100644 --- a/README.rst +++ b/README.rst @@ -5,6 +5,11 @@ RateLimiter Simple Python module providing rate limiting. +Fork +---- +Changes according to the comments in this thread: `https://github.com/RazerM/ratelimiter/issues/15 `_ + + Overview -------- diff --git a/ratelimiter/_async.py b/ratelimiter/_async.py index feb80ad..69dc5c1 100644 --- a/ratelimiter/_async.py +++ b/ratelimiter/_async.py @@ -23,12 +23,15 @@ async def __aenter__(self): # We want to ensure that no more than max_calls were run in the allowed # period. For this, we store the last timestamps of each call and run # the rate verification upon each __enter__ call. - if len(self.calls) >= self.max_calls: - until = time.time() + self.period - self._timespan - if self.callback: - asyncio.ensure_future(self.callback(until)) + + if len(self.calls) == self.max_calls: + until = self.period + self.calls[0] sleeptime = until - time.time() + if sleeptime > 0: + if self.callback: + asyncio.ensure_future(self.callback(until)) + await asyncio.sleep(sleeptime) return self diff --git a/ratelimiter/_sync.py b/ratelimiter/_sync.py index 577dfb4..ca0bcd9 100644 --- a/ratelimiter/_sync.py +++ b/ratelimiter/_sync.py @@ -23,7 +23,7 @@ def __init__(self, max_calls, period=1.0, callback=None): # We're using a deque to store the last execution timestamps, not for # its maxlen attribute, but to allow constant time front removal. - self.calls = collections.deque() + self.calls = collections.deque(maxlen=max_calls) self.period = period self.max_calls = max_calls @@ -49,14 +49,18 @@ def __enter__(self): # We want to ensure that no more than max_calls were run in the allowed # period. For this, we store the last timestamps of each call and run # the rate verification upon each __enter__ call. - if len(self.calls) >= self.max_calls: - until = time.time() + self.period - self._timespan - if self.callback: - t = threading.Thread(target=self.callback, args=(until,)) - t.daemon = True - t.start() + if len(self.calls) == self.max_calls: + until = self.period + self.calls[0] sleeptime = until - time.time() + + print('sleeptime', sleeptime, self.calls[0]) + if sleeptime > 0: + if self.callback: + t = threading.Thread(target=self.callback, args=(until,)) + t.daemon = True + t.start() + time.sleep(sleeptime) return self