Refine search
@Override public RedisClusterConnection getClusterConnection() { if (!isClusterAware()) { throw new InvalidDataAccessApiUsageException("Cluster is not configured!"); } RedisClusterClient clusterClient = (RedisClusterClient) client; return getShareNativeConnection() ? new LettuceClusterConnection( (StatefulRedisClusterConnection<byte[], byte[]>) getOrCreateSharedConnection().getConnection(), connectionProvider, clusterClient, clusterCommandExecutor, clientConfiguration.getCommandTimeout()) : new LettuceClusterConnection(null, connectionProvider, clusterClient, clusterCommandExecutor, clientConfiguration.getCommandTimeout()); }
@Override public void clusterAddSlots(RedisClusterNode node, SlotRange range) { Assert.notNull(range, "Range must not be null."); clusterAddSlots(node, range.getSlotsArray()); }
@Override public void clusterDeleteSlotsInRange(RedisClusterNode node, SlotRange range) { Assert.notNull(range, "Range must not be null."); clusterDeleteSlots(node, range.getSlotsArray()); }
@Override public RedisClusterNode clusterGetNodeForKey(byte[] key) { return clusterGetNodeForSlot(clusterGetSlotForKey(key)); }
/** * Creates new {@link LettuceClusterConnection} using {@link LettuceConnectionProvider} running commands across the * cluster via given {@link ClusterCommandExecutor}. * * @param connectionProvider must not be {@literal null}. * @since 2.0 */ public LettuceClusterConnection(LettuceConnectionProvider connectionProvider) { super(null, connectionProvider, RedisURI.DEFAULT_TIMEOUT_DURATION.toMillis(), 0); Assert.isTrue(connectionProvider instanceof ClusterConnectionProvider, "LettuceConnectionProvider must be a ClusterConnectionProvider."); this.clusterClient = getClient(); this.topologyProvider = new LettuceClusterTopologyProvider(this.clusterClient); this.clusterCommandExecutor = new ClusterCommandExecutor(this.topologyProvider, new LettuceClusterNodeResourceProvider(getConnectionProvider()), exceptionConverter); this.disposeClusterCommandExecutorOnClose = true; }
@Override public List<byte[]> bRPop(int timeout, byte[]... keys) { Assert.notNull(keys, "Keys must not be null!"); Assert.noNullElements(keys, "Keys must not contain null elements!"); if (ClusterSlotHashUtil.isSameSlotForAllKeys(keys)) { return super.bRPop(timeout, keys); } List<KeyValue<byte[], byte[]>> resultList = connection.getClusterCommandExecutor().executeMultiKeyCommand( (LettuceMultiKeyClusterCommandCallback<KeyValue<byte[], byte[]>>) (client, key) -> client.brpop(timeout, key), Arrays.asList(keys)).resultsAsList(); for (KeyValue<byte[], byte[]> kv : resultList) { if (kv != null) { return LettuceConverters.toBytesList(kv); } } return Collections.emptyList(); }
/** * Creates new {@link LettuceClusterConnection} using {@link LettuceConnectionProvider} running commands across the * cluster via given {@link ClusterCommandExecutor}. * * @param connectionProvider must not be {@literal null}. * @param executor must not be {@literal null}. * @param timeout must not be {@literal null}. * @since 2.0 */ public LettuceClusterConnection(LettuceConnectionProvider connectionProvider, ClusterCommandExecutor executor, Duration timeout) { super(null, connectionProvider, timeout.toMillis(), 0); Assert.notNull(executor, "ClusterCommandExecutor must not be null."); Assert.isTrue(connectionProvider instanceof ClusterConnectionProvider, "LettuceConnectionProvider must be a ClusterConnectionProvider."); this.clusterClient = getClient(); this.topologyProvider = new LettuceClusterTopologyProvider(this.clusterClient); this.clusterCommandExecutor = executor; this.disposeClusterCommandExecutorOnClose = false; }
@Nullable public Set<byte[]> keys(RedisClusterNode node, byte[] pattern) { Assert.notNull(pattern, "Pattern must not be null!"); return LettuceConverters.toBytesSet(connection.getClusterCommandExecutor() .executeCommandOnSingleNode((LettuceClusterCommandCallback<List<byte[]>>) client -> client.keys(pattern), node) .getValue()); }
@Override public Set<byte[]> keys(byte[] pattern) { Assert.notNull(pattern, "Pattern must not be null!"); Collection<List<byte[]>> keysPerNode = connection.getClusterCommandExecutor() .executeCommandOnAllNodes((LettuceClusterCommandCallback<List<byte[]>>) connection -> connection.keys(pattern)) .resultsAsList(); Set<byte[]> keys = new HashSet<>(); for (List<byte[]> keySet : keysPerNode) { keys.addAll(keySet); } return keys; }
private <T> NodeResult<T> executeCommandOnSingleNode(LettuceClusterCommandCallback<T> command, RedisClusterNode node) { return connection.getClusterCommandExecutor().executeCommandOnSingleNode(command, node); }
@Override public void clusterForget(RedisClusterNode node) { List<RedisClusterNode> nodes = new ArrayList<>(clusterGetNodes()); RedisClusterNode nodeToRemove = topologyProvider.getTopology().lookup(node); nodes.remove(nodeToRemove); this.clusterCommandExecutor.executeCommandAsyncOnNodes( (LettuceClusterCommandCallback<String>) client -> client.clusterForget(nodeToRemove.getId()), nodes); }
@Override public Long time() { return convertListOfStringToTime(connection.getClusterCommandExecutor() .executeCommandOnArbitraryNode((LettuceClusterCommandCallback<List<byte[]>>) RedisServerCommands::time) .getValue()); }
@Override public RedisKeyCommands keyCommands() { return doGetClusterKeyCommands(); }
private <T> MultiNodeResult<T> executeCommandOnAllNodes(final LettuceClusterCommandCallback<T> cmd) { return connection.getClusterCommandExecutor().executeCommandOnAllNodes(cmd); }
@Override public List<byte[]> clusterGetKeysInSlot(int slot, Integer count) { try { return getConnection().clusterGetKeysInSlot(slot, count); } catch (Exception ex) { throw exceptionConverter.translate(ex); } }
@Override public byte[] randomKey() { List<RedisClusterNode> nodes = connection.clusterGetNodes(); Set<RedisClusterNode> inspectedNodes = new HashSet<>(nodes.size()); do { RedisClusterNode node = nodes.get(ThreadLocalRandom.current().nextInt(nodes.size())); while (inspectedNodes.contains(node)) { node = nodes.get(ThreadLocalRandom.current().nextInt(nodes.size())); } inspectedNodes.add(node); byte[] key = randomKey(node); if (key != null && key.length > 0) { return key; } } while (nodes.size() != inspectedNodes.size()); return null; }
@Override public List<byte[]> bLPop(int timeout, byte[]... keys) { Assert.notNull(keys, "Keys must not be null!"); Assert.noNullElements(keys, "Keys must not contain null elements!"); if (ClusterSlotHashUtil.isSameSlotForAllKeys(keys)) { return super.bLPop(timeout, keys); } List<KeyValue<byte[], byte[]>> resultList = connection.getClusterCommandExecutor().executeMultiKeyCommand( (LettuceMultiKeyClusterCommandCallback<KeyValue<byte[], byte[]>>) (client, key) -> client.blpop(timeout, key), Arrays.asList(keys)).resultsAsList(); for (KeyValue<byte[], byte[]> kv : resultList) { if (kv != null) { return LettuceConverters.toBytesList(kv); } } return Collections.emptyList(); }
/** * Creates new {@link LettuceClusterConnection} using {@link LettuceConnectionProvider} running commands across the * cluster via given {@link ClusterCommandExecutor}. * * @param connectionProvider must not be {@literal null}. * @param executor must not be {@literal null}. * @param timeout must not be {@literal null}. * @since 2.0 */ public LettuceClusterConnection(LettuceConnectionProvider connectionProvider, ClusterCommandExecutor executor, Duration timeout) { super(null, connectionProvider, timeout.toMillis(), 0); Assert.notNull(executor, "ClusterCommandExecutor must not be null."); Assert.isTrue(connectionProvider instanceof ClusterConnectionProvider, "LettuceConnectionProvider must be a ClusterConnectionProvider."); this.clusterClient = getClient(); this.topologyProvider = new LettuceClusterTopologyProvider(this.clusterClient); this.clusterCommandExecutor = executor; this.disposeClusterCommandExecutorOnClose = false; }
/** * 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<byte[]> scan(RedisClusterNode node, ScanOptions options) { Assert.notNull(node, "RedisClusterNode must not be null!"); Assert.notNull(options, "Options must not be null!"); return connection.getClusterCommandExecutor() .executeCommandOnSingleNode((LettuceClusterCommandCallback<ScanCursor<byte[]>>) client -> { return new LettuceScanCursor<byte[]>(options) { @Override protected LettuceScanIteration<byte[]> doScan(io.lettuce.core.ScanCursor cursor, ScanOptions options) { ScanArgs scanArgs = LettuceConverters.toScanArgs(options); KeyScanCursor<byte[]> keyScanCursor = client.scan(cursor, scanArgs); return new LettuceScanIteration<>(keyScanCursor, keyScanCursor.getKeys()); } }.open(); }, node).getValue(); }
@Override public Set<byte[]> keys(byte[] pattern) { Assert.notNull(pattern, "Pattern must not be null!"); Collection<List<byte[]>> keysPerNode = connection.getClusterCommandExecutor() .executeCommandOnAllNodes((LettuceClusterCommandCallback<List<byte[]>>) connection -> connection.keys(pattern)) .resultsAsList(); Set<byte[]> keys = new HashSet<>(); for (List<byte[]> keySet : keysPerNode) { keys.addAll(keySet); } return keys; }