## Summary
Adds a production-safe `scan_keys(pattern, *, count=None) -> Iterator[str]` API for Redis key discovery.
- `JsonRepositoryInterface` gets a default `scan_keys()` implementation that delegates to `list_keys()`.
- `RedisAdapter` overrides it to use Redis `SCAN` via `scan_iter`, avoiding blocking `KEYS` lookups on large datasets.
- Shared pattern validation is extracted into `_validate_pattern()` and reused by `list_keys()` and `scan_keys()`.
- `list_keys()` is unchanged in behavior; its docstring now notes that it uses `KEYS` and may block.
- README documents when to prefer `scan_keys()` over `list_keys()`.
## Test plan
- [x] Unit tests for default interface fallback
- [x] Unit tests for mocked `scan_iter`, `count` forwarding, validation, and connection errors
- [x] Integration tests mirroring `list_keys` coverage for `scan_keys`
- [x] Pre-commit hooks passed (`ruff`, `mypy`, `pyupgrade`, `prettier`)
Provide a SCAN-based key iterator for Redis adapters so callers can enumerate large keyspaces without relying on blocking KEYS lookups.
Co-authored-by: Cursor <[email protected]>
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
Summary
Adds a production-safe
scan_keys(pattern, *, count=None) -> Iterator[str]API for Redis key discovery.JsonRepositoryInterfacegets a defaultscan_keys()implementation that delegates tolist_keys().RedisAdapteroverrides it to use RedisSCANviascan_iter, avoiding blockingKEYSlookups on large datasets._validate_pattern()and reused bylist_keys()andscan_keys().list_keys()is unchanged in behavior; its docstring now notes that it usesKEYSand may block.scan_keys()overlist_keys().Test plan
scan_iter,countforwarding, validation, and connection errorslist_keyscoverage forscan_keysruff,mypy,pyupgrade,prettier)Test Coverage Report: