noke / core /ratelimit.py
i3t2y
feat: noke v0.3.0 — 5-batch architecture upgrade
5039d41
Raw
History Blame Contribute Delete
1.46 kB
import time
from collections import defaultdict
from typing import Optional
class TokenBucket:
"""令牌桶限流器(每个 key 独立)"""
def __init__(self, rate: float, burst: int):
self.rate = rate # 每秒令牌数
self.burst = burst # 最大令牌数
self._tokens = defaultdict(float)
self._last = defaultdict(float)
def allow(self, key: str) -> bool:
"""返回 True 表示允许请求,False 表示限流"""
now = time.time()
# 补充令牌
last = self._last.get(key, now)
elapsed = now - last
self._last[key] = now
self._tokens[key] = min(self.burst, self._tokens.get(key, self.burst) + elapsed * self.rate)
if self._tokens[key] >= 1.0:
self._tokens[key] -= 1.0
return True
return False
class RateLimiter:
"""多 key 限流器,qps<=0 时放行"""
def __init__(self, qps: int = 0, burst: int = 0):
self.qps = qps
self.burst = burst if burst > 0 else qps
self._bucket = TokenBucket(rate=qps, burst=self.burst) if qps > 0 else None
def allow(self, key: str) -> bool:
if self._bucket is None:
return True
return self._bucket.allow(key)
def active_buckets(self) -> int:
"""返回当前活跃的 key 数量(近似)"""
if self._bucket is None:
return 0
return len(self._bucket._tokens)