/** * @param callback must not be {@literal null}. * @param nodes must not be {@literal null}. * @return never {@literal null}. * @throws ClusterCommandExecutionFailureException * @throws IllegalArgumentException in case the node could not be resolved to a topology-known node */ public <S, T> MultiNodeResult<T> executeCommandAsyncOnNodes(ClusterCommandCallback<S, T> callback, Iterable<RedisClusterNode> nodes) { Assert.notNull(callback, "Callback must not be null!"); Assert.notNull(nodes, "Nodes must not be null!"); List<RedisClusterNode> resolvedRedisClusterNodes = new ArrayList<>(); ClusterTopology topology = topologyProvider.getTopology(); for (RedisClusterNode node : nodes) { try { resolvedRedisClusterNodes.add(topology.lookup(node)); } catch (ClusterStateFailureException e) { throw new IllegalArgumentException(String.format("Node %s is unknown to cluster", node), e); } } Map<NodeExecution, Future<NodeResult<T>>> futures = new LinkedHashMap<>(); for (RedisClusterNode node : resolvedRedisClusterNodes) { futures.put(new NodeExecution(node), executor.submit(() -> executeCommandOnSingleNode(callback, node))); } return collectResults(futures); }
/** * Run {@link MultiKeyClusterCommandCallback} with on a curated set of nodes serving one or more keys. * * @param cmd must not be {@literal null}. * @return never {@literal null}. * @throws ClusterCommandExecutionFailureException */ public <S, T> MultiNodeResult<T> executeMultiKeyCommand(MultiKeyClusterCommandCallback<S, T> cmd, Iterable<byte[]> keys) { Map<RedisClusterNode, PositionalKeys> nodeKeyMap = new HashMap<>(); int index = 0; for (byte[] key : keys) { for (RedisClusterNode node : getClusterTopology().getKeyServingNodes(key)) { nodeKeyMap.computeIfAbsent(node, val -> PositionalKeys.empty()).append(PositionalKey.of(key, index++)); } } Map<NodeExecution, Future<NodeResult<T>>> futures = new LinkedHashMap<>(); for (Entry<RedisClusterNode, PositionalKeys> entry : nodeKeyMap.entrySet()) { if (entry.getKey().isMaster()) { for (PositionalKey key : entry.getValue()) { futures.put(new NodeExecution(entry.getKey(), key), executor.submit(() -> executeMultiKeyCommandOnSingleNode(cmd, entry.getKey(), key.getBytes()))); } } } return collectResults(futures); }
/** * @param callback must not be {@literal null}. * @param nodes must not be {@literal null}. * @return never {@literal null}. * @throws ClusterCommandExecutionFailureException * @throws IllegalArgumentException in case the node could not be resolved to a topology-known node */ public <S, T> MultiNodeResult<T> executeCommandAsyncOnNodes(ClusterCommandCallback<S, T> callback, Iterable<RedisClusterNode> nodes) { Assert.notNull(callback, "Callback must not be null!"); Assert.notNull(nodes, "Nodes must not be null!"); List<RedisClusterNode> resolvedRedisClusterNodes = new ArrayList<>(); ClusterTopology topology = topologyProvider.getTopology(); for (RedisClusterNode node : nodes) { try { resolvedRedisClusterNodes.add(topology.lookup(node)); } catch (ClusterStateFailureException e) { throw new IllegalArgumentException(String.format("Node %s is unknown to cluster", node), e); } } Map<NodeExecution, Future<NodeResult<T>>> futures = new LinkedHashMap<>(); for (RedisClusterNode node : resolvedRedisClusterNodes) { futures.put(new NodeExecution(node), executor.submit(() -> executeCommandOnSingleNode(callback, node))); } return collectResults(futures); }
/** * @param callback must not be {@literal null}. * @param nodes must not be {@literal null}. * @return never {@literal null}. * @throws ClusterCommandExecutionFailureException * @throws IllegalArgumentException in case the node could not be resolved to a topology-known node */ public <S, T> MultiNodeResult<T> executeCommandAsyncOnNodes(ClusterCommandCallback<S, T> callback, Iterable<RedisClusterNode> nodes) { Assert.notNull(callback, "Callback must not be null!"); Assert.notNull(nodes, "Nodes must not be null!"); List<RedisClusterNode> resolvedRedisClusterNodes = new ArrayList<>(); ClusterTopology topology = topologyProvider.getTopology(); for (RedisClusterNode node : nodes) { try { resolvedRedisClusterNodes.add(topology.lookup(node)); } catch (ClusterStateFailureException e) { throw new IllegalArgumentException(String.format("Node %s is unknown to cluster", node), e); } } Map<NodeExecution, Future<NodeResult<T>>> futures = new LinkedHashMap<>(); for (RedisClusterNode node : resolvedRedisClusterNodes) { futures.put(new NodeExecution(node), executor.submit(() -> executeCommandOnSingleNode(callback, node))); } return collectResults(futures); }
/** * Run {@link MultiKeyClusterCommandCallback} with on a curated set of nodes serving one or more keys. * * @param cmd must not be {@literal null}. * @return never {@literal null}. * @throws ClusterCommandExecutionFailureException */ public <S, T> MultiNodeResult<T> executeMultiKeyCommand(MultiKeyClusterCommandCallback<S, T> cmd, Iterable<byte[]> keys) { Map<RedisClusterNode, PositionalKeys> nodeKeyMap = new HashMap<>(); int index = 0; for (byte[] key : keys) { for (RedisClusterNode node : getClusterTopology().getKeyServingNodes(key)) { nodeKeyMap.computeIfAbsent(node, val -> PositionalKeys.empty()).append(PositionalKey.of(key, index++)); } } Map<NodeExecution, Future<NodeResult<T>>> futures = new LinkedHashMap<>(); for (Entry<RedisClusterNode, PositionalKeys> entry : nodeKeyMap.entrySet()) { if (entry.getKey().isMaster()) { for (PositionalKey key : entry.getValue()) { futures.put(new NodeExecution(entry.getKey(), key), executor.submit(() -> executeMultiKeyCommandOnSingleNode(cmd, entry.getKey(), key.getBytes()))); } } } return collectResults(futures); }
/** * Run {@link MultiKeyClusterCommandCallback} with on a curated set of nodes serving one or more keys. * * @param cmd must not be {@literal null}. * @return never {@literal null}. * @throws ClusterCommandExecutionFailureException */ public <S, T> MultiNodeResult<T> executeMultiKeyCommand(MultiKeyClusterCommandCallback<S, T> cmd, Iterable<byte[]> keys) { Map<RedisClusterNode, PositionalKeys> nodeKeyMap = new HashMap<>(); int index = 0; for (byte[] key : keys) { for (RedisClusterNode node : getClusterTopology().getKeyServingNodes(key)) { nodeKeyMap.computeIfAbsent(node, val -> PositionalKeys.empty()).append(PositionalKey.of(key, index++)); } } Map<NodeExecution, Future<NodeResult<T>>> futures = new LinkedHashMap<>(); for (Entry<RedisClusterNode, PositionalKeys> entry : nodeKeyMap.entrySet()) { if (entry.getKey().isMaster()) { for (PositionalKey key : entry.getValue()) { futures.put(new NodeExecution(entry.getKey(), key), executor.submit(() -> executeMultiKeyCommandOnSingleNode(cmd, entry.getKey(), key.getBytes()))); } } } return collectResults(futures); }