Skip to content

Instantly share code, notes, and snippets.

@akkuman
Last active July 20, 2021 09:00
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save akkuman/08909e776f9a260650cf03623c486926 to your computer and use it in GitHub Desktop.
Save akkuman/08909e776f9a260650cf03623c486926 to your computer and use it in GitHub Desktop.
[漏桶算法] 实现第一类漏桶算法 #python
#ref: https://en.wikipedia.org/wiki/Leaky_bucket#As_a_meter
class RateLimitExceededException(Exception):
pass
class LeakyBucketRateLimiter:
'''漏桶算法实现
Attributes:
capacity: 桶容量,多少份水
leaky_rate: 消费速率,以s为单位(份/s)
Raises:
RateLimitExceededException: 当漏桶溢水抛出
'''
def __init__(self, capacity=10.0, leaky_rate=1.0, is_lock=True):
self.lock = threading.RLock() if is_lock else None
self._capacity = float(capacity)
self._leak_rate = float(leaky_rate)
# 上次漏水时间
self._last_time = time.time()
# 余水
self._remained_water = float(0)
def acquire(self, how_many=1):
'''向漏桶加水
Args:
how_many: 加多少份水
'''
if self.lock:
with self.lock:
return self._acquire(how_many)
return self._acquire(how_many)
def _acquire(self, how_many):
# 计算漏桶现在余下多少水
now = time.time()
delta = self._remained_water - self._leak_rate * (now - self._last_time)
self._remained_water = float(min(0, delta))
self._last_time = now
# 向漏桶加水
if self._remained_water + how_many >= self._capacity:
# 溢水则抛出异常
raise RateLimitExceededException
self._remained_water += how_many
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment