mirror of
https://github.com/kennethreitz/responder.git
synced 2026-07-21 18:39:29 +00:00
d9f8883e66
## Summary Three targeted improvements surfaced by an audit of the framework — two reliability fixes and one CI gap. Ships as v7.1.3. ### 1. Redis rate-limit atomicity (bug fix) `RedisBackend.hit` / `AsyncRedisBackend.ahit` performed `INCR` then `EXPIRE` as two separate round-trips. If the process died (or the connection dropped) between them, the key never received a TTL — permanently rate-limiting that client until manual eviction. Both now use a single atomic Lua `EVAL` that increments and, on the first hit of a window, sets the expiry. ### 2. Background task graceful shutdown `api.background`'s `ThreadPoolExecutor` was never drained, so in-flight fire-and-forget tasks were abandoned on shutdown. Added `BackgroundQueue.shutdown()` and a registered shutdown event handler that drains the pool off the event loop. ### 3. CI now enforces lint + types `ruff` and `mypy` previously ran only in the manual release guard, so lint/type regressions could land on `main`. New `Lint & Types` workflow runs both on every push and PR. The tree passes both today. ## Tests - New `tests/test_v713_improvements.py` (7 tests): background drain/reject-after-shutdown, app-level shutdown drain, and Redis atomic-eval behavior (including a fake that fails if `incr`/`expire` are called directly). - Updated the existing fake Redis in `tests/test_round4.py` to implement `eval`. - Full suite: 740 passed, ruff clean, mypy clean. ## Notes Also corrected the stale `[Unreleased]` compare link in the changelog (pointed at v7.1.1 despite v7.1.2 shipping). 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>