Skip to content

fix(redis): deduplicate keys returned by SCAN - #199

Merged
allen0099 merged 1 commit into
masterfrom
fix/redis-get-all-keys-dedupe
Sep 26, 2026
Merged

allen0099 merged 1 commit into
masterfrom
fix/redis-get-all-keys-dedupe

Conversation

@allen0099

Copy link
Copy Markdown
Owner

Closes #173.

Problem

SCAN guarantees that every key present for the whole iteration is returned, but not that it is returned only once. When the keyspace shrinks mid-scan, a key can come back twice. _scan_keys passed duplicates through to get_all_keys(), and so to CacheManager, the monitoring routes and session enumeration.

Reproduced on Redis (redis:alpine):

  • Store 1 000 p:* keys and 60 000 other keys, and start SCAN MATCH p:* COUNT 2000.
  • After a few pages, UNLINK the other keys and continue the scan.
  • In 2 of 5 runs, the scan returned 1 001 keys, of which 1 000 were unique.

Change

_scan_keys collects keys into a dict, which deduplicates them while keeping the order in which each key was first seen. Every caller benefits: get_all_keys, get_cache_data, and the clear* methods, which also stop sending a key twice to DEL.

Tests

  • New test_redis_scan_results_are_deduplicated wraps client.scan so that each later page repeats a key already returned. It spans three SCAN pages.
  • Mutation check: without the change, only this test fails.
  • Full suite against live Redis and Memcached (CACHEX_REQUIRE_LIVE_SERVERS=1): 852 passed, 100% coverage.

SCAN may return a key more than once when the keyspace shrinks during
the iteration, and get_all_keys() passed the duplicates through to
CacheManager and the monitoring routes.

Closes #173
@allen0099 allen0099 added this to the 0.3.8 milestone Sep 26, 2026
@allen0099 allen0099 added bug Something isn't working backends Cache backends and their atomic primitives labels Sep 26, 2026
@allen0099
allen0099 merged commit 79eb66f into master Sep 26, 2026
11 checks passed
@allen0099
allen0099 deleted the fix/redis-get-all-keys-dedupe branch September 26, 2026 12:28
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

backends Cache backends and their atomic primitives bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Redis get_all_keys: deduplicate keys returned twice by SCAN

1 participant