MediumRate LimitingPython 3
Notification Rate Limiter
Throttle noisy notification channels while deduping repeated webhook or automation events.
35m3 sample tests8 hidden tests
Implement NotificationLimiter, a per-channel notification throttle with dedupe keys.
Requirements
- Constructor receives
limit,window_seconds, and injectednow. RaiseValueErroriflimit <= 0orwindow_seconds <= 0. allow(channel, dedupe_key)returns(allowed, retry_after_seconds).- A channel may send at most
limitunique dedupe keys per rolling window. - Dedupe keys are scoped per channel (the same key may be allowed on another channel).
- Repeating the same dedupe key inside the window is blocked without consuming a new slot.
- Expired records are removed on every call. A record expires when
now - timestamp >= window_seconds(half-open window). retry_after_secondsis0when allowed.- On capacity deny:
retry_after_seconds = max(0, window_seconds - (now - oldest_active_timestamp)). - On duplicate-key deny: the same formula using that key's stored timestamp.
Example
This trace separates duplicate denial from capacity denial, then crosses the half-open expiry boundary so a new key can enter.
python
1clock = {"now": 0.0}
2limiter = NotificationLimiter(2, 10.0, lambda: clock["now"])
3assert limiter.allow("slack", "a") == (True, 0.0)
4assert limiter.allow("slack", "a") == (False, 10.0) # duplicate: full window remains
5assert limiter.allow("slack", "b") == (True, 0.0)
6assert limiter.allow("slack", "c") == (False, 10.0) # channel is at capacity
7clock["now"] = 10.0
8assert limiter.allow("slack", "c") == (True, 0.0)Constraints
- Use injected time. Keep tests free of sleeps.
- Keep channels isolated.
Editor