From 84a28a1582eea4dec0e8167967dcfb13fb761b19 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Krist=C3=B3f=20T=C3=B3th?= Date: Tue, 9 Jul 2019 11:02:45 +0200 Subject: [PATCH] Remove unused rate limiter classes (sad to see you go) --- lib/tfw/decorators/rate_limiter.py | 98 ------------------------------ 1 file changed, 98 deletions(-) delete mode 100644 lib/tfw/decorators/rate_limiter.py diff --git a/lib/tfw/decorators/rate_limiter.py b/lib/tfw/decorators/rate_limiter.py deleted file mode 100644 index 5f8e253..0000000 --- a/lib/tfw/decorators/rate_limiter.py +++ /dev/null @@ -1,98 +0,0 @@ -from functools import wraps, partial -from time import time, sleep - -from tfw.decorators.lazy_property import lazy_property - - -class RateLimiter: - """ - Decorator class for rate limiting, blocking. - - When applied to a function this decorator will apply rate limiting - if the function is invoked more frequently than rate_per_seconds. - - By default rate limiting means sleeping until the next invocation time - as per __init__ parameter rate_per_seconds. - - Note that this decorator BLOCKS THE THREAD it is being executed on, - so it is only acceptable for stuff running on a separate thread. - - If this is no good for you please refer to AsyncRateLimiter in this module, - which is designed not to block and use the IOLoop it is being called from. - """ - def __init__(self, rate_per_second): - """ - :param rate_per_second: max frequency the decorated method should be - invoked with - """ - self.min_interval = 1 / float(rate_per_second) - self.fun = None - self.last_call = time() - - def action(self, seconds_to_next_call): - if seconds_to_next_call: - sleep(seconds_to_next_call) - self.fun() - - def __call__(self, fun): - @wraps(fun) - def wrapper(*args, **kwargs): - self.fun = partial(fun, *args, **kwargs) - limit_seconds = self._limit_rate() - self.action(limit_seconds) - return wrapper - - def _limit_rate(self): - seconds_since_last_call = time() - self.last_call - seconds_to_next_call = self.min_interval - seconds_since_last_call - - if seconds_to_next_call > 0: - return seconds_to_next_call - self.last_call = time() - return 0 - - -class AsyncRateLimiter(RateLimiter): - """ - Decorator class for rate limiting, non-blocking. - - The semantics of the rate limiting: - - unlike RateLimiter this decorator never blocks, instead it adds an async - callback version of the decorated function to the IOLoop - (to be executed after the rate limiting has expired). - - the timing works similarly to RateLimiter - """ - def __init__(self, rate_per_second, ioloop_factory): - """ - :param rate_per_second: max frequency the decorated method should be - invoked with - :param ioloop_factory: callable that should return an instance of the - IOLoop of the application - """ - self._ioloop_factory = ioloop_factory - self._ioloop = None - self._last_callback = None - - self._make_action_thread_safe() - super().__init__(rate_per_second=rate_per_second) - - def _make_action_thread_safe(self): - self.action = partial(self.ioloop.add_callback, self.action) - - @lazy_property - def ioloop(self): - return self._ioloop_factory() - - def action(self, seconds_to_next_call): - # pylint: disable=method-hidden - if self._last_callback: - self.ioloop.remove_timeout(self._last_callback) - - self._last_callback = self.ioloop.call_later( - seconds_to_next_call, - self.fun_with_debounce - ) - - def fun_with_debounce(self): - self.last_call = time() - self.fun()