From a8afab93d5cdbc121a7763fb5f97c2a9fab59874 Mon Sep 17 00:00:00 2001 From: Mark Paluch Date: Wed, 16 Oct 2019 21:14:02 +0200 Subject: [PATCH] Consider ReadFrom.isOrderSensitive() in cluster scan command #1146 ReadFrom order sensitivity is now considered in Cluster SCAN for keys. --- .../lettuce/core/cluster/ClusterScanSupport.java | 9 ++++++++- .../core/cluster/ScanIteratorIntegrationTests.java | 14 ++++++++++++++ 2 files changed, 22 insertions(+), 1 deletion(-) diff --git a/src/main/java/io/lettuce/core/cluster/ClusterScanSupport.java b/src/main/java/io/lettuce/core/cluster/ClusterScanSupport.java index 76ab91d4cf..b5b5a3e08c 100644 --- a/src/main/java/io/lettuce/core/cluster/ClusterScanSupport.java +++ b/src/main/java/io/lettuce/core/cluster/ClusterScanSupport.java @@ -18,6 +18,7 @@ import java.util.ArrayList; import java.util.Iterator; import java.util.List; +import java.util.concurrent.ThreadLocalRandom; import java.util.function.Function; import reactor.core.publisher.Mono; @@ -158,7 +159,13 @@ public Iterator iterator() { }); if (!selection.isEmpty()) { - RedisClusterNode selectedNode = (RedisClusterNode) selection.get(0); + + int indexToUse = 0; + if (!OrderingReadFromAccessor.isOrderSensitive(connection.getReadFrom())) { + indexToUse = ThreadLocalRandom.current().nextInt(selection.size()); + } + + RedisClusterNode selectedNode = (RedisClusterNode) selection.get(indexToUse); nodeIds.add(selectedNode.getNodeId()); continue; } diff --git a/src/test/java/io/lettuce/core/cluster/ScanIteratorIntegrationTests.java b/src/test/java/io/lettuce/core/cluster/ScanIteratorIntegrationTests.java index fdef446eb0..130849db39 100644 --- a/src/test/java/io/lettuce/core/cluster/ScanIteratorIntegrationTests.java +++ b/src/test/java/io/lettuce/core/cluster/ScanIteratorIntegrationTests.java @@ -49,6 +49,7 @@ class ScanIteratorIntegrationTests extends TestSupport { @Inject ScanIteratorIntegrationTests(StatefulRedisClusterConnection connection) { this.connection = connection; + this.connection.setReadFrom(ReadFrom.MASTER); this.redis = connection.sync(); } @@ -103,6 +104,19 @@ void keysMultiPass() { assertThat(keys).containsAll(KeysAndValues.KEYS); } + @Test + void keysMultiPassFromAnyNode() { + + redis.mset(KeysAndValues.MAP); + this.connection.setReadFrom(ReadFrom.ANY); + + ScanIterator scan = ScanIterator.scan(redis); + + List keys = scan.stream().collect(Collectors.toList()); + + assertThat(keys).containsAll(KeysAndValues.KEYS); + } + @Test void hscanShouldThrowNoSuchElementExceptionOnEmpty() {