Files
responder/.github/workflows
kennethreitz d9f8883e66 Harden background shutdown and Redis rate limiting; gate CI on lint/types (#610)
## 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>
2026-07-01 12:22:31 -04:00
..