I've been reading through the responses here: What's a good rate limiting algorithm?
The reply from Carlos A. Ibarra works great without asynchronous capabilities, but is there any way I can amend it to work asynchronously?
import time
def RateLimited(maxPerSecond):
minInterval = 1.0 / float(maxPerSecond)
def decorate(func):
lastTimeCalled = [0.0]
def rateLimitedFunction(*args,**kargs):
elapsed = time.clock() - lastTimeCalled[0]
leftToWait = minInterval - elapsed
if leftToWait>0:
time.sleep(leftToWait)
ret = func(*args,**kargs)
lastTimeCalled[0] = time.clock()
return ret
return rateLimitedFunction
return decorate
@RateLimited(2) # 2 per second at most
def PrintNumber(num):
print num
if __name__ == "__main__":
print "This should print 1,2,3... at about 2 per second."
for i in range(1,100):
PrintNumber(i)
Changing time.sleep(leftToWait)
to await asyncio.sleep(leftToWait)
and awaiting PrintNumber(i)
works for the first instance, but none thereafter. I'm really new at Python and trying my best to obey an API's rate limit.
My implementation:
def rate_limited(max_per_second):
min_interval = 1.0 / float(max_per_second)
def decorate(func):
last_time_called = [0.0]
async def rate_limited_function(*args, **kargs):
elapsed = time.clock() - last_time_called[0]
left_to_wait = min_interval - elapsed
if left_to_wait > 0:
await asyncio.sleep(left_to_wait)
ret = func(*args, **kargs)
last_time_called[0] = time.clock()
return ret
return rate_limited_function
return decorate
class Test:
def __init__(self, bot):
self.bot = bot
@commands.command(hidden=True, pass_context=True)
@checks.serverowner()
async def test1(self, ctx):
await self.print_number()
@rate_limited(0.1)
def print_number(self):
print("TEST")