Pseudocode:
python
def rate_limit(key, count, seconds, memo={}):
"""Rate limit resource identified by key to count per seconds.
>>> while True:
... wait = next(rate_limit('some key', 5, 8))
... if not wait:
... break
... else:
... time.sleep(wait)
... do_rate_limited_work()
"""
if (key, count, seconds) in memo:
return memo[key, count, seconds]
assert isinstance(count, int) and count > 0
def meter():
rate = float(count) / seconds
last = time.time()
tally = count
while True:
now = time.time()
extent = now - last
last = now
tally += extent * rate
if tally > count:
tally = count
elif tally < 1:
yield (1 - tally) / rate
else:
tally -= 1
yield 0
limiter = meter()
memo[key, count, seconds] = limiter
return limiter
Need to track last and tally in Cache. Might be better to build as a separate object. The generator pattern is not that useful. But the algorithm is tested and correct.
该提问来源于开源项目:grantjenks/python-diskcache