Skip to content

Reuse RxIteratorConsumer in RedissonKeysRx instead of duplicating the SCAN-cursor loop - #7312

Merged
mrniko merged 1 commit into
redisson:masterfrom
stlahxm:fix/rx-keys-scan-consumer
Aug 24, 2026
Merged

mrniko merged 1 commit into
redisson:masterfrom
stlahxm:fix/rx-keys-scan-consumer

Conversation

@stlahxm

@stlahxm stlahxm commented Aug 21, 2026 •

Copy link
Copy Markdown
Contributor

Closes #7311

RedissonKeysRx.createKeysIterator() re-implemented the backpressure-aware SCAN cursor loop (request counting, cursor advancement, completion signaling) locally instead of extending RxIteratorConsumer, which already provides the same loop and is used by SetRxIterator, RedissonMapRxIterator, and RedissonArrayRx.

The Reactor-based equivalent, RedissonKeysReactive, already delegates to its shared abstraction (IteratorConsumer) with the same two extension points this change now uses (tryAgain(), scanIterator(client, nextIterPos)), so this brings RedissonKeysRx in line with the existing pattern rather than introducing a new one.

This isn't purely cosmetic: the duplicated loop was the site of a real bug before (#5425, fixed in 0fae241aa), and that fix was applied only inside this file rather than in the shared consumer. Keeping a second copy means any future fix to RxIteratorConsumer won't reach this class automatically.

Changes

  • RedissonKeysRx.createKeysIterator(): replaced the hand-rolled LongConsumer (35 lines) with an anonymous RxIteratorConsumer<String> subclass (8 lines). No behavioral change intended.
  • RedissonKeysRxTest: added two tests exercising code paths the existing suite didn't cover:
    • testGetKeysEmptyDatabase: empty keyspace completes without hanging or erroring.
    • testGetKeysPartialRequestReturnsExactCount: requesting fewer items than exist via take(5) while the chunk size forces multiple SCAN round-trips still returns the exact count, no duplicates, matching the requested pattern.

Testing

Ran the full RedissonKeysRxTest suite (10 tests, including the two new ones) against a real Redis instance:

Test set: org.redisson.rx.RedissonKeysRxTest
Tests run: 10, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 21.58 s -- in org.redisson.rx.RedissonKeysRxTest

Also ran all 18 test classes under org.redisson.rx to check for second-order effects, since RxIteratorConsumer is shared by three other classes.

A handful of unrelated failures showed up (a TTL-timing assertion, a batch write-timeout threshold, a connection-leak timeout, and a classpath error that only appeared when running a single test class in isolation).
None of them touch getKeys()/RKeysRx, and re-running them in isolation showed the timing-sensitive ones are flaky rather than consistently broken.

I did not verify these same failures occur on unmodified master, but the affected classes (RedissonMapCacheRx, RedissonBatchRx's cluster/timeout paths) don't reference RxIteratorConsumer or RedissonKeysRx at all, so they're outside this change's blast radius.

@stlahxm
stlahxm force-pushed the fix/rx-keys-scan-consumer branch from 5c65d58 to 69f2553 Compare August 21, 2026 05:51
@mrniko mrniko added this to the 4.8.0 milestone Aug 24, 2026
@mrniko
mrniko merged commit 8aafc4b into redisson:master Aug 24, 2026
4 checks passed
@mrniko

mrniko commented Aug 24, 2026

Copy link
Copy Markdown
Member

Thanks for contribution

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Development

Successfully merging this pull request may close these issues.

RedissonKeysRx duplicates the SCAN-cursor iteration logic that RxIteratorConsumer already provides

2 participants