RazerM / ratelimiter

Simple Python module providing rate limiting
Apache License 2.0
120 stars 29 forks source link

Broken algorithm #15

Open louisabraham opened 2 years ago

louisabraham commented 2 years ago

The algorithm will always wait too much.

import time
from ratelimiter import RateLimiter

rate_limiter = RateLimiter(max_calls=1, period=1)

start = time.time()
for i in range(3):
    with rate_limiter:
        print("%.02f" % (time.time()  - start))
        time.sleep(1)

outputs

0.00
2.00
4.01

I would expect it to output 0 1 2

louisabraham commented 2 years ago

This simple code works

class RateLimiter:

    def __init__(self, max_calls, period):
        self.calls = collections.deque(maxlen=max_calls)
        self.period = period
        self.max_calls = max_calls

    def wait(self):
        if len(self.calls) == self.max_calls:
            wait = self.period + self.calls[0] - time.time()
            if wait > 0:
                time.sleep(wait)
        self.calls.append(time.time())
holasoftware commented 1 year ago

Hi Louis! I forked the repository and I changed the code according to your suggestion: https://github.com/holasoftware/ratelimiter

This code works as you expected:

import time
from ratelimiter import RateLimiter

rate_limiter = RateLimiter(max_calls=1, period=1)

start = time.time()
for i in range(3):
    with rate_limiter:
        print("%.02f" % (time.time()  - start))
    time.sleep(1)
louisabraham commented 1 year ago

Great! I also published my code there