M41: harden trust boundaries and delivery
This commit is contained in:
@@ -47,3 +47,26 @@ class FailedAttemptLimiter:
|
||||
def reset(self, key: str) -> None:
|
||||
with self._lock:
|
||||
self._failures.pop(key, None)
|
||||
|
||||
|
||||
class SlidingWindowLimiter:
|
||||
"""Thread-safe request limiter where every accepted request consumes capacity."""
|
||||
|
||||
def __init__(self, *, max_requests: int, window_seconds: float) -> None:
|
||||
self.max_requests = max_requests
|
||||
self.window_seconds = window_seconds
|
||||
self._requests: dict[str, deque[float]] = {}
|
||||
self._lock = threading.Lock()
|
||||
|
||||
def consume(self, key: str) -> int:
|
||||
"""Record an accepted request, or return the seconds until capacity is available."""
|
||||
now = time.monotonic()
|
||||
with self._lock:
|
||||
bucket = self._requests.setdefault(key, deque())
|
||||
cutoff = now - self.window_seconds
|
||||
while bucket and bucket[0] <= cutoff:
|
||||
bucket.popleft()
|
||||
if len(bucket) >= self.max_requests:
|
||||
return max(1, int(bucket[0] + self.window_seconds - now + 0.999))
|
||||
bucket.append(now)
|
||||
return 0
|
||||
|
||||
Reference in New Issue
Block a user