Skip to content

Instantly share code, notes, and snippets.

@sintezcs
Last active February 16, 2017 07:41
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save sintezcs/1efbcf903fb8749cdc7557b140719ec4 to your computer and use it in GitHub Desktop.
Save sintezcs/1efbcf903fb8749cdc7557b140719ec4 to your computer and use it in GitHub Desktop.
Rate-limiting decorator
import threading
import time
def rate_limited(max_per_second):
lock = threading.Lock()
min_interval = 1.0 / max_per_second
def decorate(func):
last_time_called = time.perf_counter()
@wraps(func)
def rate_limited_function(*args, **kwargs):
lock.acquire()
nonlocal last_time_called
elapsed = time.perf_counter() - last_time_called
left_to_wait = min_interval - elapsed
if left_to_wait > 0:
time.sleep(left_to_wait)
ret = func(*args, **kwargs)
last_time_called = time.perf_counter()
lock.release()
return ret
return rate_limited_function
return decorate
@xiaofud
Copy link

xiaofud commented Feb 16, 2017

Hi!
I think it's better to use with lock in case there is any exception raised from func, and then the lock won't be released.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment