diff options
| author | Scott <[email protected]> | 2022-01-08 15:21:25 -0800 |
|---|---|---|
| committer | Scott <[email protected]> | 2022-01-08 15:21:25 -0800 |
| commit | f5015d539e319ffcd8a4b9a7e8891c67d0d754b3 (patch) | |
| tree | ee08702d877c70e61764c6ceb0c2a1862514508e /decorator_utils.py | |
| parent | 48a2eb5656508e2d1d16e6f22e979bed5ee682a6 (diff) | |
Add rate limiter decorator.
Diffstat (limited to 'decorator_utils.py')
| -rw-r--r-- | decorator_utils.py | 28 |
1 files changed, 26 insertions, 2 deletions
diff --git a/decorator_utils.py b/decorator_utils.py index 4f98a6d..480543a 100644 --- a/decorator_utils.py +++ b/decorator_utils.py @@ -2,7 +2,6 @@ """Decorators.""" -import datetime import enum import functools import inspect @@ -15,7 +14,7 @@ import sys import threading import time import traceback -from typing import Callable, Optional +from typing import Any, Callable, Optional import warnings # This module is commonly used by others in here and should avoid @@ -58,6 +57,31 @@ def invocation_logged(func: Callable) -> Callable: return wrapper_invocation_logged +def rate_limited(n_per_second: int) -> Callable: + """Limit invocation of a wrapped function to n calls per second. + Thread safe. + + """ + min_interval = 1.0 / float(n_per_second) + + def wrapper_rate_limited(func: Callable) -> Callable: + last_invocation_time = [0.0] + + def wrapper_wrapper_rate_limited(*args, **kargs) -> Any: + while True: + elapsed = time.clock_gettime(0) - last_invocation_time[0] + wait_time = min_interval - elapsed + if wait_time > 0.0: + time.sleep(wait_time) + else: + break + ret = func(*args, **kargs) + last_invocation_time[0] = time.clock_gettime(0) + return ret + return wrapper_wrapper_rate_limited + return wrapper_rate_limited + + def debug_args(func: Callable) -> Callable: """Print the function signature and return value at each call.""" |
