diff --git a/src/main/java/org/springframework/data/redis/connection/jedis/JedisClusterKeyCommands.java b/src/main/java/org/springframework/data/redis/connection/jedis/JedisClusterKeyCommands.java index 070279a46..5350a799e 100644 --- a/src/main/java/org/springframework/data/redis/connection/jedis/JedisClusterKeyCommands.java +++ b/src/main/java/org/springframework/data/redis/connection/jedis/JedisClusterKeyCommands.java @@ -171,10 +171,18 @@ class JedisClusterKeyCommands implements RedisKeyCommands { throw new InvalidDataAccessApiUsageException("Scan is not supported across multiple nodes within a cluster"); } + /** + * Use a {@link Cursor} to iterate over keys stored at the given {@link RedisClusterNode}. + * + * @param node must not be {@literal null}. + * @param options must not be {@literal null}. + * @return never {@literal null}. + * @since 2.1 + */ Cursor scan(RedisClusterNode node, ScanOptions options) { Assert.notNull(node, "RedisClusterNode must not be null!"); - Assert.notNull(options, "Pattern must not be null!"); + Assert.notNull(options, "Options must not be null!"); return connection.getClusterCommandExecutor() .executeCommandOnSingleNode((JedisClusterCommandCallback>) client -> { diff --git a/src/main/java/org/springframework/data/redis/connection/lettuce/LettuceClusterKeyCommands.java b/src/main/java/org/springframework/data/redis/connection/lettuce/LettuceClusterKeyCommands.java index 96da36125..4137eea35 100644 --- a/src/main/java/org/springframework/data/redis/connection/lettuce/LettuceClusterKeyCommands.java +++ b/src/main/java/org/springframework/data/redis/connection/lettuce/LettuceClusterKeyCommands.java @@ -183,10 +183,18 @@ class LettuceClusterKeyCommands extends LettuceKeyCommands { .getValue()); } + /** + * Use a {@link Cursor} to iterate over keys stored at the given {@link RedisClusterNode}. + * + * @param node must not be {@literal null}. + * @param options must not be {@literal null}. + * @return never {@literal null}. + * @since 2.1 + */ Cursor scan(RedisClusterNode node, ScanOptions options) { Assert.notNull(node, "RedisClusterNode must not be null!"); - Assert.notNull(options, "Pattern must not be null!"); + Assert.notNull(options, "Options must not be null!"); return connection.getClusterCommandExecutor() .executeCommandOnSingleNode((LettuceClusterCommandCallback>) client -> { @@ -195,12 +203,11 @@ class LettuceClusterKeyCommands extends LettuceKeyCommands { @Override protected LettuceScanIteration doScan(io.lettuce.core.ScanCursor cursor, ScanOptions options) { + ScanArgs scanArgs = connection.getScanArgs(options); KeyScanCursor keyScanCursor = client.scan(cursor, scanArgs); - List keys = keyScanCursor.getKeys(); - - return new LettuceScanIteration<>(keyScanCursor, keys); + return new LettuceScanIteration<>(keyScanCursor, keyScanCursor.getKeys()); } }.open(); diff --git a/src/main/java/org/springframework/data/redis/connection/lettuce/LettuceScanCursor.java b/src/main/java/org/springframework/data/redis/connection/lettuce/LettuceScanCursor.java index d9f7c402e..7f1ec6158 100644 --- a/src/main/java/org/springframework/data/redis/connection/lettuce/LettuceScanCursor.java +++ b/src/main/java/org/springframework/data/redis/connection/lettuce/LettuceScanCursor.java @@ -27,14 +27,14 @@ import org.springframework.lang.Nullable; * across a Redis Cluster. *

* The cursor state uses Lettuce's stateful {@link io.lettuce.core.ScanCursor} to keep track of scanning progress. - * Lettuce's cursor stores scanning progress inside its cursor so using a primitive {@code long} is not sufficient. * * @author Mark Paluch + * @author Christoph Strobl * @since 2.1 */ abstract class LettuceScanCursor extends ScanCursor { - @Nullable private io.lettuce.core.ScanCursor state; + private @Nullable io.lettuce.core.ScanCursor state; /** * Creates a new {@link LettuceScanCursor} given {@link ScanOptions}. @@ -93,19 +93,22 @@ abstract class LettuceScanCursor extends ScanCursor { * * @param cursor must not be {@literal null}. * @param options must not be {@literal null}. - * @return + * @return never {@literal null} */ protected abstract LettuceScanIteration doScan(io.lettuce.core.ScanCursor cursor, ScanOptions options); /** * Lettuce-specific extension to {@link ScanIteration} keeping track of the original * {@link io.lettuce.core.ScanCursor} object. + * + * @author Mark Paluch */ static class LettuceScanIteration extends ScanIteration { private final io.lettuce.core.ScanCursor cursor; LettuceScanIteration(io.lettuce.core.ScanCursor cursor, Collection items) { + super(Long.parseLong(cursor.getCursor()), items); this.cursor = cursor; }