From 2d3370566b28ecf60128e73d682d051940b6894b Mon Sep 17 00:00:00 2001 From: skyjiang <470623352@qq.com> Date: Wed, 29 May 2024 17:21:34 +0800 Subject: [PATCH 1/7] Support readonly command on replicas node --- .../java/redis/clients/jedis/Connection.java | 5 +++ .../jedis/DefaultJedisClientConfig.java | 25 ++++++++++-- .../clients/jedis/JedisClientConfig.java | 4 ++ .../clients/jedis/JedisClusterInfoCache.java | 38 +++++++++++++++++++ .../redis/clients/jedis/UnifiedJedis.java | 4 ++ .../executors/ClusterCommandExecutor.java | 12 +++++- .../jedis/executors/CommandExecutor.java | 4 ++ .../providers/ClusterConnectionProvider.java | 26 +++++++++++++ 8 files changed, 113 insertions(+), 5 deletions(-) diff --git a/src/main/java/redis/clients/jedis/Connection.java b/src/main/java/redis/clients/jedis/Connection.java index 9325de80d7..8a31353258 100644 --- a/src/main/java/redis/clients/jedis/Connection.java +++ b/src/main/java/redis/clients/jedis/Connection.java @@ -435,6 +435,11 @@ private void initializeFromClientConfig(final JedisClientConfig config) { } } + // set readonly flag to ALL connections (including master nodes) when enable read from replica + if (config.isReadOnlyForReplica()) { + fireAndForgetMsg.add(new CommandArguments(Command.READONLY)); + } + for (CommandArguments arg : fireAndForgetMsg) { sendCommand(arg); } diff --git a/src/main/java/redis/clients/jedis/DefaultJedisClientConfig.java b/src/main/java/redis/clients/jedis/DefaultJedisClientConfig.java index 6d62646a5e..98fa4677d8 100644 --- a/src/main/java/redis/clients/jedis/DefaultJedisClientConfig.java +++ b/src/main/java/redis/clients/jedis/DefaultJedisClientConfig.java @@ -26,11 +26,13 @@ public final class DefaultJedisClientConfig implements JedisClientConfig { private final ClientSetInfoConfig clientSetInfoConfig; + private final boolean readOnlyForReplica; + private DefaultJedisClientConfig(RedisProtocol protocol, int connectionTimeoutMillis, int soTimeoutMillis, int blockingSocketTimeoutMillis, Supplier credentialsProvider, int database, String clientName, boolean ssl, SSLSocketFactory sslSocketFactory, SSLParameters sslParameters, HostnameVerifier hostnameVerifier, HostAndPortMapper hostAndPortMapper, - ClientSetInfoConfig clientSetInfoConfig) { + ClientSetInfoConfig clientSetInfoConfig, boolean readOnlyForReplica) { this.redisProtocol = protocol; this.connectionTimeoutMillis = connectionTimeoutMillis; this.socketTimeoutMillis = soTimeoutMillis; @@ -44,6 +46,7 @@ private DefaultJedisClientConfig(RedisProtocol protocol, int connectionTimeoutMi this.hostnameVerifier = hostnameVerifier; this.hostAndPortMapper = hostAndPortMapper; this.clientSetInfoConfig = clientSetInfoConfig; + this.readOnlyForReplica = readOnlyForReplica; } @Override @@ -122,6 +125,11 @@ public ClientSetInfoConfig getClientSetInfoConfig() { return clientSetInfoConfig; } + @Override + public boolean isReadOnlyForReplica() { + return readOnlyForReplica; + } + public static Builder builder() { return new Builder(); } @@ -149,6 +157,8 @@ public static class Builder { private ClientSetInfoConfig clientSetInfoConfig = ClientSetInfoConfig.DEFAULT; + private boolean readOnlyForReplicas = false; + private Builder() { } @@ -160,7 +170,8 @@ public DefaultJedisClientConfig build() { return new DefaultJedisClientConfig(redisProtocol, connectionTimeoutMillis, socketTimeoutMillis, blockingSocketTimeoutMillis, credentialsProvider, database, clientName, ssl, - sslSocketFactory, sslParameters, hostnameVerifier, hostAndPortMapper, clientSetInfoConfig); + sslSocketFactory, sslParameters, hostnameVerifier, hostAndPortMapper, clientSetInfoConfig, + readOnlyForReplicas); } /** @@ -255,6 +266,11 @@ public Builder clientSetInfoConfig(ClientSetInfoConfig setInfoConfig) { this.clientSetInfoConfig = setInfoConfig; return this; } + + public Builder readOnlyForReplicas() { + this.readOnlyForReplicas = true; + return this; + } } public static DefaultJedisClientConfig create(int connectionTimeoutMillis, int soTimeoutMillis, @@ -264,7 +280,8 @@ public static DefaultJedisClientConfig create(int connectionTimeoutMillis, int s return new DefaultJedisClientConfig(null, connectionTimeoutMillis, soTimeoutMillis, blockingSocketTimeoutMillis, new DefaultRedisCredentialsProvider(new DefaultRedisCredentials(user, password)), database, - clientName, ssl, sslSocketFactory, sslParameters, hostnameVerifier, hostAndPortMapper, null); + clientName, ssl, sslSocketFactory, sslParameters, hostnameVerifier, hostAndPortMapper, null, + false); } public static DefaultJedisClientConfig copyConfig(JedisClientConfig copy) { @@ -273,6 +290,6 @@ public static DefaultJedisClientConfig copyConfig(JedisClientConfig copy) { copy.getBlockingSocketTimeoutMillis(), copy.getCredentialsProvider(), copy.getDatabase(), copy.getClientName(), copy.isSsl(), copy.getSslSocketFactory(), copy.getSslParameters(), copy.getHostnameVerifier(), copy.getHostAndPortMapper(), - copy.getClientSetInfoConfig()); + copy.getClientSetInfoConfig(), copy.isReadOnlyForReplica()); } } diff --git a/src/main/java/redis/clients/jedis/JedisClientConfig.java b/src/main/java/redis/clients/jedis/JedisClientConfig.java index 0ad6e979f6..57b172cb34 100644 --- a/src/main/java/redis/clients/jedis/JedisClientConfig.java +++ b/src/main/java/redis/clients/jedis/JedisClientConfig.java @@ -80,6 +80,10 @@ default HostAndPortMapper getHostAndPortMapper() { return null; } + default boolean isReadOnlyForReplica() { + return false; + } + /** * Modify the behavior of internally executing CLIENT SETINFO command. * @return CLIENT SETINFO config diff --git a/src/main/java/redis/clients/jedis/JedisClusterInfoCache.java b/src/main/java/redis/clients/jedis/JedisClusterInfoCache.java index da88462ef4..7d93757d35 100644 --- a/src/main/java/redis/clients/jedis/JedisClusterInfoCache.java +++ b/src/main/java/redis/clients/jedis/JedisClusterInfoCache.java @@ -38,6 +38,8 @@ public class JedisClusterInfoCache { private final Map nodes = new HashMap<>(); private final ConnectionPool[] slots = new ConnectionPool[Protocol.CLUSTER_HASHSLOTS]; private final HostAndPort[] slotNodes = new HostAndPort[Protocol.CLUSTER_HASHSLOTS]; + private List[] replicaSlots; + private List[] replicaSlotNodes; private final ReentrantReadWriteLock rwl = new ReentrantReadWriteLock(); private final Lock r = rwl.readLock(); @@ -85,6 +87,10 @@ public JedisClusterInfoCache(final JedisClientConfig clientConfig, topologyRefreshExecutor.scheduleWithFixedDelay(new TopologyRefreshTask(), topologyRefreshPeriod.toMillis(), topologyRefreshPeriod.toMillis(), TimeUnit.MILLISECONDS); } + if (clientConfig.isReadOnlyForReplica()) { + replicaSlots = new ArrayList[Protocol.CLUSTER_HASHSLOTS]; + replicaSlotNodes = new ArrayList[Protocol.CLUSTER_HASHSLOTS]; + } } /** @@ -144,6 +150,8 @@ public void discoverClusterNodesAndSlots(Connection jedis) { setupNodeIfNotExist(targetNode); if (i == MASTER_NODE_INDEX) { assignSlotsToNode(slotNums, targetNode); + } else if (clientConfig.isReadOnlyForReplica()) { + assignSlotsToReplicaNode(slotNums, targetNode); } } } @@ -236,6 +244,8 @@ private void discoverClusterSlots(Connection jedis) { setupNodeIfNotExist(targetNode); if (i == MASTER_NODE_INDEX) { assignSlotsToNode(slotNums, targetNode); + } else if (clientConfig.isReadOnlyForReplica()) { + assignSlotsToReplicaNode(slotNums, targetNode); } } } @@ -307,6 +317,25 @@ public void assignSlotsToNode(List targetSlots, HostAndPort targetNode) } } + public void assignSlotsToReplicaNode(List targetSlots, HostAndPort targetNode) { + w.lock(); + try { + ConnectionPool targetPool = setupNodeIfNotExist(targetNode); + for (Integer slot : targetSlots) { + if (replicaSlots[slot] == null) { + replicaSlots[slot] = new ArrayList<>(); + } + replicaSlots[slot].add(targetPool); + if (replicaSlotNodes[slot] == null) { + replicaSlotNodes[slot] = new ArrayList<>(); + } + replicaSlotNodes[slot].add(targetNode); + } + } finally { + w.unlock(); + } + } + public ConnectionPool getNode(String nodeKey) { r.lock(); try { @@ -338,6 +367,15 @@ public HostAndPort getSlotNode(int slot) { } } + public List getSlotReplicaPools(int slot) { + r.lock(); + try { + return replicaSlots[slot]; + } finally { + r.unlock(); + } + } + public Map getNodes() { r.lock(); try { diff --git a/src/main/java/redis/clients/jedis/UnifiedJedis.java b/src/main/java/redis/clients/jedis/UnifiedJedis.java index 398b1302ba..c063b6143c 100644 --- a/src/main/java/redis/clients/jedis/UnifiedJedis.java +++ b/src/main/java/redis/clients/jedis/UnifiedJedis.java @@ -256,6 +256,10 @@ public final T executeCommand(CommandObject commandObject) { return executor.executeCommand(commandObject); } + public final T executeCommandToReplica(CommandObject commandObject) { + return executor.executeCommandToReplica(commandObject); + } + public final T broadcastCommand(CommandObject commandObject) { return executor.broadcastCommand(commandObject); } diff --git a/src/main/java/redis/clients/jedis/executors/ClusterCommandExecutor.java b/src/main/java/redis/clients/jedis/executors/ClusterCommandExecutor.java index 375db99e14..cc9b28c211 100644 --- a/src/main/java/redis/clients/jedis/executors/ClusterCommandExecutor.java +++ b/src/main/java/redis/clients/jedis/executors/ClusterCommandExecutor.java @@ -73,6 +73,15 @@ public final T broadcastCommand(CommandObject commandObject) { @Override public final T executeCommand(CommandObject commandObject) { + return doExecuteCommand(commandObject, false); + } + + @Override + public final T executeCommandToReplica(CommandObject commandObject) { + return doExecuteCommand(commandObject, true); + } + + private T doExecuteCommand(CommandObject commandObject, boolean toReplica) { Instant deadline = Instant.now().plus(maxTotalRetriesDuration); JedisRedirectionException redirect = null; @@ -88,7 +97,8 @@ public final T executeCommand(CommandObject commandObject) { connection.executeCommand(Protocol.Command.ASKING); } } else { - connection = provider.getConnection(commandObject.getArguments()); + connection = toReplica ? provider.getReplicaConnection(commandObject.getArguments()) + : provider.getConnection(commandObject.getArguments()); } return execute(connection, commandObject); diff --git a/src/main/java/redis/clients/jedis/executors/CommandExecutor.java b/src/main/java/redis/clients/jedis/executors/CommandExecutor.java index 85ec034b02..7b7c6ff225 100644 --- a/src/main/java/redis/clients/jedis/executors/CommandExecutor.java +++ b/src/main/java/redis/clients/jedis/executors/CommandExecutor.java @@ -6,6 +6,10 @@ public interface CommandExecutor extends AutoCloseable { T executeCommand(CommandObject commandObject); + default T executeCommandToReplica(CommandObject commandObject) { + return executeCommand(commandObject); + } + default T broadcastCommand(CommandObject commandObject) { return executeCommand(commandObject); } diff --git a/src/main/java/redis/clients/jedis/providers/ClusterConnectionProvider.java b/src/main/java/redis/clients/jedis/providers/ClusterConnectionProvider.java index c21640713d..925645e169 100644 --- a/src/main/java/redis/clients/jedis/providers/ClusterConnectionProvider.java +++ b/src/main/java/redis/clients/jedis/providers/ClusterConnectionProvider.java @@ -6,6 +6,8 @@ import java.util.List; import java.util.Map; import java.util.Set; +import java.util.concurrent.ThreadLocalRandom; + import org.apache.commons.pool2.impl.GenericObjectPoolConfig; import redis.clients.jedis.ClusterCommandArguments; @@ -102,6 +104,11 @@ public Connection getConnection(CommandArguments args) { return slot >= 0 ? getConnectionFromSlot(slot) : getConnection(); } + public Connection getReplicaConnection(CommandArguments args) { + final int slot = ((ClusterCommandArguments) args).getCommandHashSlot(); + return slot >= 0 ? getReplicaConnectionFromSlot(slot) : getConnection(); + } + @Override public Connection getConnection() { // In antirez's redis-rb-cluster implementation, getRandomConnection always @@ -158,6 +165,25 @@ public Connection getConnectionFromSlot(int slot) { } } + public Connection getReplicaConnectionFromSlot(int slot) { + List connectionPools = cache.getSlotReplicaPools(slot); + ThreadLocalRandom random = ThreadLocalRandom.current(); + if (connectionPools != null && !connectionPools.isEmpty()) { + // pick up randomly a connection + int idx = random.nextInt(connectionPools.size()); + return connectionPools.get(idx).getResource(); + } + + renewSlotCache(); + connectionPools = cache.getSlotReplicaPools(slot); + if (connectionPools != null && !connectionPools.isEmpty()) { + int idx = random.nextInt(connectionPools.size()); + return connectionPools.get(idx).getResource(); + } + + return getConnectionFromSlot(slot); + } + @Override public Map getConnectionMap() { return Collections.unmodifiableMap(getNodes()); From a8b0d2c6cd245fc281c12629e1683a3b4fa8dcdf Mon Sep 17 00:00:00 2001 From: anotherJJz <470623352@qq.com> Date: Thu, 8 Aug 2024 16:12:03 +0800 Subject: [PATCH 2/7] Add test case --- .../redis/clients/jedis/JedisClusterTest.java | 26 +++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/src/test/java/redis/clients/jedis/JedisClusterTest.java b/src/test/java/redis/clients/jedis/JedisClusterTest.java index 8297eb90c6..edaf32829d 100644 --- a/src/test/java/redis/clients/jedis/JedisClusterTest.java +++ b/src/test/java/redis/clients/jedis/JedisClusterTest.java @@ -199,6 +199,32 @@ public void testReadonlyAndReadwrite() throws Exception { nodeSlave2.flushDB(); } + @Test + public void testReadFromReplicas() throws Exception { + node1.clusterMeet(LOCAL_IP, nodeInfoSlave2.getPort()); + JedisClusterTestUtil.waitForClusterReady(node1, node2, node3, nodeSlave2); + + for (String nodeInfo : node2.clusterNodes().split("\n")) { + if (nodeInfo.contains("myself")) { + nodeSlave2.clusterReplicate(nodeInfo.split(" ")[0]); + break; + } + } + + DefaultJedisClientConfig READ_REPLICAS_CLIENT_CONFIG + = DefaultJedisClientConfig.builder().password("cluster").readOnlyForReplicas().build(); + try (JedisCluster jedisCluster = new JedisCluster(nodeInfo1, READ_REPLICAS_CLIENT_CONFIG, + DEFAULT_REDIRECTIONS, DEFAULT_POOL_CONFIG)) { + assertEquals("OK", jedisCluster.set("test", "read-from-replicas")); + + ClusterCommandObjects commandObjects = new ClusterCommandObjects(); + assertEquals("read-from-replicas", jedisCluster.executeCommandToReplica(commandObjects.get("test"))); + } + + nodeSlave2.clusterReset(ClusterResetType.SOFT); + nodeSlave2.flushDB(); + } + /** * slot->nodes 15363 node3 e */ From b0dc0bb50e6f41c56cc24f0c6045bbfd943d2914 Mon Sep 17 00:00:00 2001 From: anotherJJz <470623352@qq.com> Date: Fri, 9 Aug 2024 09:39:18 +0800 Subject: [PATCH 3/7] Update src/main/java/redis/clients/jedis/JedisClusterInfoCache.java Co-authored-by: M Sazzadul Hoque <7600764+sazzad16@users.noreply.github.com> --- src/main/java/redis/clients/jedis/JedisClusterInfoCache.java | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/main/java/redis/clients/jedis/JedisClusterInfoCache.java b/src/main/java/redis/clients/jedis/JedisClusterInfoCache.java index 7d93757d35..a337171fbb 100644 --- a/src/main/java/redis/clients/jedis/JedisClusterInfoCache.java +++ b/src/main/java/redis/clients/jedis/JedisClusterInfoCache.java @@ -90,6 +90,9 @@ public JedisClusterInfoCache(final JedisClientConfig clientConfig, if (clientConfig.isReadOnlyForReplica()) { replicaSlots = new ArrayList[Protocol.CLUSTER_HASHSLOTS]; replicaSlotNodes = new ArrayList[Protocol.CLUSTER_HASHSLOTS]; + } else { + replicaSlots = null; + replicaSlotNodes = null; } } From f6cdaef0c0864ff699a5f9f9f6748c533eb99e82 Mon Sep 17 00:00:00 2001 From: anotherJJz <470623352@qq.com> Date: Fri, 9 Aug 2024 09:39:32 +0800 Subject: [PATCH 4/7] Update src/main/java/redis/clients/jedis/JedisClusterInfoCache.java Co-authored-by: M Sazzadul Hoque <7600764+sazzad16@users.noreply.github.com> --- src/main/java/redis/clients/jedis/JedisClusterInfoCache.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/redis/clients/jedis/JedisClusterInfoCache.java b/src/main/java/redis/clients/jedis/JedisClusterInfoCache.java index a337171fbb..cf83d893ec 100644 --- a/src/main/java/redis/clients/jedis/JedisClusterInfoCache.java +++ b/src/main/java/redis/clients/jedis/JedisClusterInfoCache.java @@ -38,8 +38,8 @@ public class JedisClusterInfoCache { private final Map nodes = new HashMap<>(); private final ConnectionPool[] slots = new ConnectionPool[Protocol.CLUSTER_HASHSLOTS]; private final HostAndPort[] slotNodes = new HostAndPort[Protocol.CLUSTER_HASHSLOTS]; - private List[] replicaSlots; - private List[] replicaSlotNodes; + private final List[] replicaSlots; + private final List[] replicaSlotNodes; private final ReentrantReadWriteLock rwl = new ReentrantReadWriteLock(); private final Lock r = rwl.readLock(); From 6f5da44b3030cc4f8bc720b5c91e3235fda74381 Mon Sep 17 00:00:00 2001 From: anotherJJz <470623352@qq.com> Date: Fri, 9 Aug 2024 09:54:28 +0800 Subject: [PATCH 5/7] fix for review --- src/main/java/redis/clients/jedis/JedisCluster.java | 8 ++++++++ .../java/redis/clients/jedis/JedisClusterInfoCache.java | 7 ------- src/main/java/redis/clients/jedis/UnifiedJedis.java | 4 ---- .../clients/jedis/executors/ClusterCommandExecutor.java | 1 - .../redis/clients/jedis/executors/CommandExecutor.java | 4 ---- 5 files changed, 8 insertions(+), 16 deletions(-) diff --git a/src/main/java/redis/clients/jedis/JedisCluster.java b/src/main/java/redis/clients/jedis/JedisCluster.java index 6c5843c16e..68d8f4205f 100644 --- a/src/main/java/redis/clients/jedis/JedisCluster.java +++ b/src/main/java/redis/clients/jedis/JedisCluster.java @@ -7,6 +7,7 @@ import org.apache.commons.pool2.impl.GenericObjectPoolConfig; +import redis.clients.jedis.executors.ClusterCommandExecutor; import redis.clients.jedis.providers.ClusterConnectionProvider; import redis.clients.jedis.util.JedisClusterCRC16; @@ -266,4 +267,11 @@ public ClusterPipeline pipelined() { public AbstractTransaction transaction(boolean doMulti) { throw new UnsupportedOperationException(); } + + public final T executeCommandToReplica(CommandObject commandObject) { + if (!(executor instanceof ClusterCommandExecutor)) { + throw new UnsupportedOperationException("Support only execute to replica in ClusterCommandExecutor"); + } + return ((ClusterCommandExecutor) executor).executeCommandToReplica(commandObject); + } } diff --git a/src/main/java/redis/clients/jedis/JedisClusterInfoCache.java b/src/main/java/redis/clients/jedis/JedisClusterInfoCache.java index cf83d893ec..79be093ffb 100644 --- a/src/main/java/redis/clients/jedis/JedisClusterInfoCache.java +++ b/src/main/java/redis/clients/jedis/JedisClusterInfoCache.java @@ -39,7 +39,6 @@ public class JedisClusterInfoCache { private final ConnectionPool[] slots = new ConnectionPool[Protocol.CLUSTER_HASHSLOTS]; private final HostAndPort[] slotNodes = new HostAndPort[Protocol.CLUSTER_HASHSLOTS]; private final List[] replicaSlots; - private final List[] replicaSlotNodes; private final ReentrantReadWriteLock rwl = new ReentrantReadWriteLock(); private final Lock r = rwl.readLock(); @@ -89,10 +88,8 @@ public JedisClusterInfoCache(final JedisClientConfig clientConfig, } if (clientConfig.isReadOnlyForReplica()) { replicaSlots = new ArrayList[Protocol.CLUSTER_HASHSLOTS]; - replicaSlotNodes = new ArrayList[Protocol.CLUSTER_HASHSLOTS]; } else { replicaSlots = null; - replicaSlotNodes = null; } } @@ -329,10 +326,6 @@ public void assignSlotsToReplicaNode(List targetSlots, HostAndPort targ replicaSlots[slot] = new ArrayList<>(); } replicaSlots[slot].add(targetPool); - if (replicaSlotNodes[slot] == null) { - replicaSlotNodes[slot] = new ArrayList<>(); - } - replicaSlotNodes[slot].add(targetNode); } } finally { w.unlock(); diff --git a/src/main/java/redis/clients/jedis/UnifiedJedis.java b/src/main/java/redis/clients/jedis/UnifiedJedis.java index c063b6143c..398b1302ba 100644 --- a/src/main/java/redis/clients/jedis/UnifiedJedis.java +++ b/src/main/java/redis/clients/jedis/UnifiedJedis.java @@ -256,10 +256,6 @@ public final T executeCommand(CommandObject commandObject) { return executor.executeCommand(commandObject); } - public final T executeCommandToReplica(CommandObject commandObject) { - return executor.executeCommandToReplica(commandObject); - } - public final T broadcastCommand(CommandObject commandObject) { return executor.broadcastCommand(commandObject); } diff --git a/src/main/java/redis/clients/jedis/executors/ClusterCommandExecutor.java b/src/main/java/redis/clients/jedis/executors/ClusterCommandExecutor.java index cc9b28c211..e5049672b8 100644 --- a/src/main/java/redis/clients/jedis/executors/ClusterCommandExecutor.java +++ b/src/main/java/redis/clients/jedis/executors/ClusterCommandExecutor.java @@ -76,7 +76,6 @@ public final T executeCommand(CommandObject commandObject) { return doExecuteCommand(commandObject, false); } - @Override public final T executeCommandToReplica(CommandObject commandObject) { return doExecuteCommand(commandObject, true); } diff --git a/src/main/java/redis/clients/jedis/executors/CommandExecutor.java b/src/main/java/redis/clients/jedis/executors/CommandExecutor.java index 7b7c6ff225..85ec034b02 100644 --- a/src/main/java/redis/clients/jedis/executors/CommandExecutor.java +++ b/src/main/java/redis/clients/jedis/executors/CommandExecutor.java @@ -6,10 +6,6 @@ public interface CommandExecutor extends AutoCloseable { T executeCommand(CommandObject commandObject); - default T executeCommandToReplica(CommandObject commandObject) { - return executeCommand(commandObject); - } - default T broadcastCommand(CommandObject commandObject) { return executeCommand(commandObject); } From 79b5ee5f432254d19b39abca0c7ea70451c86f0a Mon Sep 17 00:00:00 2001 From: M Sazzadul Hoque <7600764+sazzad16@users.noreply.github.com> Date: Sun, 11 Aug 2024 20:24:13 +0600 Subject: [PATCH 6/7] Add a TODO comment for test --- src/test/java/redis/clients/jedis/JedisClusterTest.java | 1 + 1 file changed, 1 insertion(+) diff --git a/src/test/java/redis/clients/jedis/JedisClusterTest.java b/src/test/java/redis/clients/jedis/JedisClusterTest.java index edaf32829d..a7e6aca70b 100644 --- a/src/test/java/redis/clients/jedis/JedisClusterTest.java +++ b/src/test/java/redis/clients/jedis/JedisClusterTest.java @@ -219,6 +219,7 @@ public void testReadFromReplicas() throws Exception { ClusterCommandObjects commandObjects = new ClusterCommandObjects(); assertEquals("read-from-replicas", jedisCluster.executeCommandToReplica(commandObjects.get("test"))); + // TODO: ensure data being served from replica node(s) } nodeSlave2.clusterReset(ClusterResetType.SOFT); From bd1ea66dc6c21d956f9774073a83d9dbc96bd92f Mon Sep 17 00:00:00 2001 From: anotherJJz <470623352@qq.com> Date: Mon, 12 Aug 2024 16:17:28 +0800 Subject: [PATCH 7/7] Update src/test/java/redis/clients/jedis/JedisClusterTest.java Co-authored-by: M Sazzadul Hoque <7600764+sazzad16@users.noreply.github.com> --- src/test/java/redis/clients/jedis/JedisClusterTest.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/test/java/redis/clients/jedis/JedisClusterTest.java b/src/test/java/redis/clients/jedis/JedisClusterTest.java index a7e6aca70b..2308bb4b07 100644 --- a/src/test/java/redis/clients/jedis/JedisClusterTest.java +++ b/src/test/java/redis/clients/jedis/JedisClusterTest.java @@ -213,11 +213,11 @@ public void testReadFromReplicas() throws Exception { DefaultJedisClientConfig READ_REPLICAS_CLIENT_CONFIG = DefaultJedisClientConfig.builder().password("cluster").readOnlyForReplicas().build(); + ClusterCommandObjects commandObjects = new ClusterCommandObjects(); try (JedisCluster jedisCluster = new JedisCluster(nodeInfo1, READ_REPLICAS_CLIENT_CONFIG, DEFAULT_REDIRECTIONS, DEFAULT_POOL_CONFIG)) { assertEquals("OK", jedisCluster.set("test", "read-from-replicas")); - ClusterCommandObjects commandObjects = new ClusterCommandObjects(); assertEquals("read-from-replicas", jedisCluster.executeCommandToReplica(commandObjects.get("test"))); // TODO: ensure data being served from replica node(s) }