Introduce LettuceInvoker.
We now use LettuceInvoker to call Lettuce API methods for synchronous, pipelining, and transactional execution models. LettuceInvoker captures the method invocation as functional utility and allows conversion of results: Long result = invoker.just(RedisGeoAsyncCommands::geoadd, key, point.getX(), point.getY(), member); List<byte[]> result = invoker.fromMany(RedisGeoAsyncCommands::geohash, key, members) .toList(it -> it.getValueOrElse(null)); Closes #1797 Original Pull Request #1948
This commit is contained in:
committed by
Christoph Strobl
parent
c95d54732a
commit
96fa2ecd70
@@ -75,6 +75,7 @@ public interface RedisListCommands {
|
||||
* @see <a href="https://redis.io/commands/lpos">Redis Documentation: LPOS</a>
|
||||
* @since 2.4
|
||||
*/
|
||||
@Nullable
|
||||
List<Long> lPos(byte[] key, byte[] element, @Nullable Integer rank, @Nullable Integer count);
|
||||
|
||||
/**
|
||||
|
||||
@@ -38,14 +38,9 @@ class LettuceClusterHyperLogLogCommands extends LettuceHyperLogLogCommands {
|
||||
public Long pfCount(byte[]... keys) {
|
||||
|
||||
if (ClusterSlotHashUtil.isSameSlotForAllKeys(keys)) {
|
||||
|
||||
try {
|
||||
return super.pfCount(keys);
|
||||
} catch (Exception ex) {
|
||||
throw convertLettuceAccessException(ex);
|
||||
}
|
||||
|
||||
return super.pfCount(keys);
|
||||
}
|
||||
|
||||
throw new InvalidDataAccessApiUsageException("All keys must map to same slot for pfcount in cluster mode.");
|
||||
}
|
||||
|
||||
@@ -59,14 +54,10 @@ class LettuceClusterHyperLogLogCommands extends LettuceHyperLogLogCommands {
|
||||
byte[][] allKeys = ByteUtils.mergeArrays(destinationKey, sourceKeys);
|
||||
|
||||
if (ClusterSlotHashUtil.isSameSlotForAllKeys(allKeys)) {
|
||||
try {
|
||||
super.pfMerge(destinationKey, sourceKeys);
|
||||
return;
|
||||
} catch (Exception ex) {
|
||||
throw convertLettuceAccessException(ex);
|
||||
}
|
||||
|
||||
super.pfMerge(destinationKey, sourceKeys);
|
||||
return;
|
||||
}
|
||||
|
||||
throw new InvalidDataAccessApiUsageException("All keys must map to same slot for pfmerge in cluster mode.");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -20,7 +20,6 @@ import static io.lettuce.core.protocol.CommandType.*;
|
||||
import io.lettuce.core.AbstractRedisClient;
|
||||
import io.lettuce.core.LettuceFutures;
|
||||
import io.lettuce.core.RedisClient;
|
||||
import io.lettuce.core.RedisException;
|
||||
import io.lettuce.core.RedisFuture;
|
||||
import io.lettuce.core.RedisURI;
|
||||
import io.lettuce.core.TransactionResult;
|
||||
@@ -53,7 +52,6 @@ import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.Future;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.concurrent.atomic.AtomicLong;
|
||||
import java.util.function.Function;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
import org.springframework.beans.BeanUtils;
|
||||
@@ -108,7 +106,7 @@ public class LettuceConnection extends AbstractRedisConnection {
|
||||
private boolean isClosed = false;
|
||||
private boolean isMulti = false;
|
||||
private boolean isPipelined = false;
|
||||
private @Nullable List<LettuceResult> ppline;
|
||||
private @Nullable List<LettuceResult<?, ?>> ppline;
|
||||
private @Nullable PipeliningFlushState flushState;
|
||||
private final Queue<FutureResult<?>> txResults = new LinkedList<>();
|
||||
private volatile @Nullable LettuceSubscription subscription;
|
||||
@@ -116,22 +114,20 @@ public class LettuceConnection extends AbstractRedisConnection {
|
||||
private boolean convertPipelineAndTxResults = true;
|
||||
private PipeliningFlushPolicy pipeliningFlushPolicy = PipeliningFlushPolicy.flushEachCommand();
|
||||
|
||||
LettuceResult newLettuceResult(Future<?> resultHolder) {
|
||||
LettuceResult<?, ?> newLettuceResult(Future<?> resultHolder) {
|
||||
return newLettuceResult(resultHolder, (val) -> val);
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
<T, R> LettuceResult<T, R> newLettuceResult(Future<T> resultHolder, Converter<T, R> converter) {
|
||||
|
||||
return LettuceResultBuilder.forResponse(resultHolder).mappedWith((Converter) converter)
|
||||
return LettuceResultBuilder.<T, R> forResponse(resultHolder).mappedWith(converter)
|
||||
.convertPipelineAndTxResults(convertPipelineAndTxResults).build();
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
<T, R> LettuceResult<T, R> newLettuceResult(Future<T> resultHolder, Converter<T, R> converter,
|
||||
Supplier<R> defaultValue) {
|
||||
|
||||
return LettuceResultBuilder.forResponse(resultHolder).mappedWith((Converter) converter)
|
||||
return LettuceResultBuilder.<T, R> forResponse(resultHolder).mappedWith(converter)
|
||||
.convertPipelineAndTxResults(convertPipelineAndTxResults).defaultNullTo(defaultValue).build();
|
||||
}
|
||||
|
||||
@@ -372,17 +368,6 @@ public class LettuceConnection extends AbstractRedisConnection {
|
||||
return new LettuceZSetCommands(this);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@SuppressWarnings({ "rawtypes", "unchecked" })
|
||||
private Object await(RedisFuture<?> cmd) {
|
||||
|
||||
if (isMulti) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return LettuceFutures.awaitOrCancel(cmd, timeout, TimeUnit.MILLISECONDS);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object execute(String command, byte[]... args) {
|
||||
return execute(command, null, args);
|
||||
@@ -402,40 +387,22 @@ public class LettuceConnection extends AbstractRedisConnection {
|
||||
public Object execute(String command, @Nullable CommandOutput commandOutputTypeHint, byte[]... args) {
|
||||
|
||||
Assert.hasText(command, "a valid command needs to be specified");
|
||||
try {
|
||||
|
||||
String name = command.trim().toUpperCase();
|
||||
CommandType commandType = CommandType.valueOf(name);
|
||||
String name = command.trim().toUpperCase();
|
||||
CommandType commandType = CommandType.valueOf(name);
|
||||
|
||||
validateCommandIfRunningInTransactionMode(commandType, args);
|
||||
validateCommandIfRunningInTransactionMode(commandType, args);
|
||||
|
||||
CommandArgs<byte[], byte[]> cmdArg = new CommandArgs<>(CODEC);
|
||||
if (!ObjectUtils.isEmpty(args)) {
|
||||
cmdArg.addKeys(args);
|
||||
}
|
||||
|
||||
RedisClusterAsyncCommands<byte[], byte[]> connectionImpl = getAsyncConnection();
|
||||
|
||||
CommandOutput expectedOutput = commandOutputTypeHint != null ? commandOutputTypeHint
|
||||
: typeHints.getTypeHint(commandType);
|
||||
Command cmd = new Command(commandType, expectedOutput, cmdArg);
|
||||
|
||||
if (isPipelined()) {
|
||||
|
||||
pipeline(newLettuceResult(connectionImpl.dispatch(cmd.getType(), cmd.getOutput(), cmd.getArgs())));
|
||||
return null;
|
||||
}
|
||||
|
||||
if (isQueueing()) {
|
||||
|
||||
transaction(newLettuceResult(connectionImpl.dispatch(cmd.getType(), cmd.getOutput(), cmd.getArgs())));
|
||||
return null;
|
||||
}
|
||||
|
||||
return await(connectionImpl.dispatch(cmd.getType(), cmd.getOutput(), cmd.getArgs()));
|
||||
} catch (RedisException ex) {
|
||||
throw convertLettuceAccessException(ex);
|
||||
CommandArgs<byte[], byte[]> cmdArg = new CommandArgs<>(CODEC);
|
||||
if (!ObjectUtils.isEmpty(args)) {
|
||||
cmdArg.addKeys(args);
|
||||
}
|
||||
|
||||
CommandOutput expectedOutput = commandOutputTypeHint != null ? commandOutputTypeHint
|
||||
: typeHints.getTypeHint(commandType);
|
||||
Command cmd = new Command(commandType, expectedOutput, cmdArg);
|
||||
|
||||
return invoke().just(RedisClusterAsyncCommands::dispatch, cmd.getType(), cmd.getOutput(), cmd.getArgs());
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -600,36 +567,12 @@ public class LettuceConnection extends AbstractRedisConnection {
|
||||
*/
|
||||
@Override
|
||||
public byte[] echo(byte[] message) {
|
||||
try {
|
||||
if (isPipelined()) {
|
||||
pipeline(newLettuceResult(getAsyncConnection().echo(message)));
|
||||
return null;
|
||||
}
|
||||
if (isQueueing()) {
|
||||
transaction(newLettuceResult(getAsyncConnection().echo(message)));
|
||||
return null;
|
||||
}
|
||||
return getConnection().echo(message);
|
||||
} catch (Exception ex) {
|
||||
throw convertLettuceAccessException(ex);
|
||||
}
|
||||
return invoke().just(RedisClusterAsyncCommands::echo, message);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String ping() {
|
||||
try {
|
||||
if (isPipelined()) {
|
||||
pipeline(newLettuceResult(getAsyncConnection().ping()));
|
||||
return null;
|
||||
}
|
||||
if (isQueueing()) {
|
||||
transaction(newLettuceResult(getAsyncConnection().ping()));
|
||||
return null;
|
||||
}
|
||||
return getConnection().ping();
|
||||
} catch (Exception ex) {
|
||||
throw convertLettuceAccessException(ex);
|
||||
}
|
||||
return invoke().just(RedisClusterAsyncCommands::ping);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -703,29 +646,15 @@ public class LettuceConnection extends AbstractRedisConnection {
|
||||
+ "Use separate ConnectionFactorys to work with multiple databases");
|
||||
}
|
||||
|
||||
try {
|
||||
this.dbIndex = dbIndex;
|
||||
|
||||
this.dbIndex = dbIndex;
|
||||
|
||||
if (isPipelined()) {
|
||||
pipeline(new LettuceStatusResult(getAsyncConnection().dispatch(CommandType.SELECT,
|
||||
new StatusOutput<>(ByteArrayCodec.INSTANCE), new CommandArgs<>(ByteArrayCodec.INSTANCE).add(dbIndex))));
|
||||
return;
|
||||
}
|
||||
|
||||
if (isQueueing()) {
|
||||
transaction(newLettuceStatusResult(getAsyncConnection().dispatch(CommandType.SELECT,
|
||||
new StatusOutput<>(ByteArrayCodec.INSTANCE), new CommandArgs<>(ByteArrayCodec.INSTANCE).add(dbIndex))));
|
||||
return;
|
||||
}
|
||||
((RedisCommands) getConnection()).select(dbIndex);
|
||||
} catch (Exception ex) {
|
||||
throw convertLettuceAccessException(ex);
|
||||
}
|
||||
invokeStatus().just(RedisClusterAsyncCommands::dispatch, CommandType.SELECT,
|
||||
new StatusOutput<>(ByteArrayCodec.INSTANCE), new CommandArgs<>(ByteArrayCodec.INSTANCE).add(dbIndex));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void unwatch() {
|
||||
|
||||
try {
|
||||
if (isPipelined()) {
|
||||
pipeline(newLettuceStatusResult(getAsyncDedicatedRedisCommands().unwatch()));
|
||||
@@ -771,23 +700,7 @@ public class LettuceConnection extends AbstractRedisConnection {
|
||||
*/
|
||||
@Override
|
||||
public Long publish(byte[] channel, byte[] message) {
|
||||
|
||||
try {
|
||||
|
||||
if (isPipelined()) {
|
||||
pipeline(newLettuceResult(getAsyncConnection().publish(channel, message)));
|
||||
return null;
|
||||
}
|
||||
|
||||
if (isQueueing()) {
|
||||
transaction(newLettuceResult(getAsyncConnection().publish(channel, message)));
|
||||
return null;
|
||||
}
|
||||
|
||||
return getConnection().publish(channel, message);
|
||||
} catch (Exception ex) {
|
||||
throw convertLettuceAccessException(ex);
|
||||
}
|
||||
return invoke().just(RedisClusterAsyncCommands::publish, channel, message);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -887,13 +800,6 @@ public class LettuceConnection extends AbstractRedisConnection {
|
||||
this.pipeliningFlushPolicy = pipeliningFlushPolicy;
|
||||
}
|
||||
|
||||
private void checkSubscription() {
|
||||
if (isSubscribed()) {
|
||||
throw new RedisSubscribedConnectionException(
|
||||
"Connection already subscribed; use the connection Subscription to cancel or add new channels");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@link #close()} the current connection and open a new pub/sub connection to the Redis server.
|
||||
*
|
||||
@@ -906,10 +812,6 @@ public class LettuceConnection extends AbstractRedisConnection {
|
||||
return connectionProvider.getConnection(StatefulRedisPubSubConnection.class);
|
||||
}
|
||||
|
||||
private LettuceSubscription initSubscription(MessageListener listener) {
|
||||
return doCreateSubscription(listener, switchToPubSub(), connectionProvider);
|
||||
}
|
||||
|
||||
/**
|
||||
* Customization hook to create a {@link LettuceSubscription}.
|
||||
*
|
||||
@@ -924,7 +826,7 @@ public class LettuceConnection extends AbstractRedisConnection {
|
||||
return new LettuceSubscription(listener, connection, connectionProvider);
|
||||
}
|
||||
|
||||
void pipeline(LettuceResult result) {
|
||||
void pipeline(LettuceResult<?, ?> result) {
|
||||
|
||||
if (flushState != null) {
|
||||
flushState.onCommand(getOrCreateDedicatedConnection());
|
||||
@@ -937,77 +839,90 @@ public class LettuceConnection extends AbstractRedisConnection {
|
||||
}
|
||||
}
|
||||
|
||||
<S, T> void executeInPipeline(Function<RedisClusterAsyncCommands, RedisFuture<S>> command,
|
||||
Converter<S, T> converter) {
|
||||
|
||||
try {
|
||||
pipeline(newLettuceResult(command.apply(getAsyncConnection()), converter));
|
||||
} catch (Exception ex) {
|
||||
throw convertLettuceAccessException(ex);
|
||||
}
|
||||
/**
|
||||
* Obtain a {@link LettuceInvoker} to call Lettuce methods using the default {@link #getAsyncConnection() connection}.
|
||||
*
|
||||
* @return the {@link LettuceInvoker}.
|
||||
* @since 2.5
|
||||
*/
|
||||
LettuceInvoker invoke() {
|
||||
return invoke(getAsyncConnection());
|
||||
}
|
||||
|
||||
<S, T> void executeInTx(Function<RedisClusterAsyncCommands, RedisFuture<S>> command, Converter<S, T> converter) {
|
||||
|
||||
try {
|
||||
transaction(newLettuceResult(command.apply(getAsyncConnection()), converter));
|
||||
} catch (Exception ex) {
|
||||
throw convertLettuceAccessException(ex);
|
||||
}
|
||||
/**
|
||||
* Obtain a {@link LettuceInvoker} to call Lettuce methods using the given {@link RedisClusterAsyncCommands
|
||||
* connection}.
|
||||
*
|
||||
* @param connection the connection to use.
|
||||
* @return the {@link LettuceInvoker}.
|
||||
* @since 2.5
|
||||
*/
|
||||
LettuceInvoker invoke(RedisClusterAsyncCommands<byte[], byte[]> connection) {
|
||||
return doInvoke(connection, false);
|
||||
}
|
||||
|
||||
<T> NullableResult<T> execute(Function<RedisClusterCommands, T> command) {
|
||||
|
||||
try {
|
||||
|
||||
T result = command.apply(getConnection());
|
||||
return NullableResult.of(result);
|
||||
} catch (Exception ex) {
|
||||
throw convertLettuceAccessException(ex);
|
||||
}
|
||||
/**
|
||||
* Obtain a {@link LettuceInvoker} to call Lettuce methods returning a status response using the default
|
||||
* {@link #getAsyncConnection() connection}. Status responses are not included in transactional and pipeline results.
|
||||
*
|
||||
* @return the {@link LettuceInvoker}.
|
||||
* @since 2.5
|
||||
*/
|
||||
LettuceInvoker invokeStatus() {
|
||||
return doInvoke(getAsyncConnection(), true);
|
||||
}
|
||||
|
||||
<T> RedisFuture<T> executeAsync(Function<RedisClusterAsyncCommands, RedisFuture<T>> command) {
|
||||
|
||||
try {
|
||||
return command.apply(getAsyncConnection());
|
||||
} catch (Exception ex) {
|
||||
throw convertLettuceAccessException(ex);
|
||||
}
|
||||
}
|
||||
|
||||
<S, T> T invoke(RedisFuture<S> future, Converter<S, T> converter) {
|
||||
private LettuceInvoker doInvoke(RedisClusterAsyncCommands<byte[], byte[]> connection, boolean statusCommand) {
|
||||
|
||||
if (isPipelined()) {
|
||||
pipeline(newLettuceResult(future, converter));
|
||||
return null;
|
||||
|
||||
return new LettuceInvoker(connection, (future, converter, nullDefault) -> {
|
||||
|
||||
try {
|
||||
if (statusCommand) {
|
||||
pipeline(newLettuceStatusResult(future.get()));
|
||||
} else {
|
||||
pipeline(newLettuceResult(future.get(), converter, nullDefault));
|
||||
}
|
||||
} catch (Exception ex) {
|
||||
throw convertLettuceAccessException(ex);
|
||||
}
|
||||
return null;
|
||||
});
|
||||
}
|
||||
|
||||
if (isQueueing()) {
|
||||
transaction(newLettuceResult(future, converter));
|
||||
return null;
|
||||
}
|
||||
return NullableResult.of((S) await(future)).convert(converter).get();
|
||||
}
|
||||
|
||||
<T> T execute(Function<RedisClusterCommands, T> sync, Function<RedisClusterAsyncCommands, RedisFuture<T>> async) {
|
||||
return execute(sync, async, val -> val);
|
||||
}
|
||||
return new LettuceInvoker(connection, (future, converter, nullDefault) -> {
|
||||
try {
|
||||
if (statusCommand) {
|
||||
transaction(newLettuceStatusResult(future.get()));
|
||||
} else {
|
||||
transaction(newLettuceResult(future.get(), converter, nullDefault));
|
||||
}
|
||||
|
||||
// use a future here and only async.
|
||||
<S, T> T execute(Function<RedisClusterCommands, S> sync, Function<RedisClusterAsyncCommands, RedisFuture<S>> async,
|
||||
Converter<S, T> converter) {
|
||||
|
||||
if (isPipelined()) {
|
||||
executeInPipeline(async, converter);
|
||||
return null;
|
||||
}
|
||||
if (isQueueing()) {
|
||||
executeInTx(async, converter);
|
||||
return null;
|
||||
} catch (Exception ex) {
|
||||
throw convertLettuceAccessException(ex);
|
||||
}
|
||||
return null;
|
||||
});
|
||||
}
|
||||
|
||||
// return execute(sync).convert(converter).get();
|
||||
return NullableResult.of((S) await(executeAsync(async))).convert(converter).get();
|
||||
return new LettuceInvoker(connection, (future, converter, nullDefault) -> {
|
||||
|
||||
try {
|
||||
|
||||
Object result = await(future.get());
|
||||
|
||||
if (result == null) {
|
||||
return nullDefault.get();
|
||||
}
|
||||
|
||||
return converter.convert(result);
|
||||
} catch (Exception ex) {
|
||||
throw convertLettuceAccessException(ex);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
void transaction(FutureResult<?> result) {
|
||||
@@ -1015,14 +930,19 @@ public class LettuceConnection extends AbstractRedisConnection {
|
||||
}
|
||||
|
||||
RedisClusterAsyncCommands<byte[], byte[]> getAsyncConnection() {
|
||||
|
||||
if (isQueueing()) {
|
||||
return getAsyncDedicatedConnection();
|
||||
}
|
||||
|
||||
if (asyncSharedConn != null) {
|
||||
|
||||
if (asyncSharedConn instanceof StatefulRedisConnection) {
|
||||
return ((StatefulRedisConnection<byte[], byte[]>) asyncSharedConn).async();
|
||||
}
|
||||
if (asyncSharedConn instanceof StatefulRedisClusterConnection) {
|
||||
return ((StatefulRedisClusterConnection<byte[], byte[]>) asyncSharedConn).async();
|
||||
}
|
||||
}
|
||||
return getAsyncDedicatedConnection();
|
||||
}
|
||||
@@ -1032,6 +952,7 @@ public class LettuceConnection extends AbstractRedisConnection {
|
||||
if (isQueueing()) {
|
||||
return getDedicatedConnection();
|
||||
}
|
||||
|
||||
if (asyncSharedConn != null) {
|
||||
|
||||
if (asyncSharedConn instanceof StatefulRedisConnection) {
|
||||
@@ -1041,12 +962,8 @@ public class LettuceConnection extends AbstractRedisConnection {
|
||||
return ((StatefulRedisClusterConnection<byte[], byte[]>) asyncSharedConn).sync();
|
||||
}
|
||||
}
|
||||
return getDedicatedConnection();
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private RedisAsyncCommands<byte[], byte[]> getAsyncDedicatedRedisCommands() {
|
||||
return (RedisAsyncCommands) getAsyncDedicatedConnection();
|
||||
return getDedicatedConnection();
|
||||
}
|
||||
|
||||
RedisClusterCommands<byte[], byte[]> getDedicatedConnection() {
|
||||
@@ -1079,6 +996,69 @@ public class LettuceConnection extends AbstractRedisConnection {
|
||||
String.format("%s is not a supported connection type.", connection.getClass().getName()));
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
protected StatefulConnection<byte[], byte[]> doGetAsyncDedicatedConnection() {
|
||||
|
||||
StatefulConnection connection = connectionProvider.getConnection(StatefulConnection.class);
|
||||
|
||||
if (customizedDatabaseIndex()) {
|
||||
potentiallySelectDatabase(dbIndex);
|
||||
}
|
||||
|
||||
return connection;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean isActive(RedisNode node) {
|
||||
|
||||
StatefulRedisSentinelConnection<String, String> connection = null;
|
||||
try {
|
||||
connection = getConnection(node);
|
||||
return connection.sync().ping().equalsIgnoreCase("pong");
|
||||
} catch (Exception e) {
|
||||
return false;
|
||||
} finally {
|
||||
if (connection != null) {
|
||||
connectionProvider.release(connection);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.redis.connection.AbstractRedisConnection#getSentinelConnection(org.springframework.data.redis.connection.RedisNode)
|
||||
*/
|
||||
@Override
|
||||
protected RedisSentinelConnection getSentinelConnection(RedisNode sentinel) {
|
||||
|
||||
StatefulRedisSentinelConnection<String, String> connection = getConnection(sentinel);
|
||||
return new LettuceSentinelConnection(connection);
|
||||
}
|
||||
|
||||
LettuceConnectionProvider getConnectionProvider() {
|
||||
return connectionProvider;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private StatefulRedisSentinelConnection<String, String> getConnection(RedisNode sentinel) {
|
||||
return ((TargetAware) connectionProvider).getConnection(StatefulRedisSentinelConnection.class,
|
||||
getRedisURI(sentinel));
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private <T> T await(RedisFuture<T> cmd) {
|
||||
|
||||
if (isMulti) {
|
||||
return null;
|
||||
}
|
||||
|
||||
try {
|
||||
return LettuceFutures.awaitOrCancel(cmd, timeout, TimeUnit.MILLISECONDS);
|
||||
} catch (RuntimeException e) {
|
||||
throw convertLettuceAccessException(e);
|
||||
}
|
||||
}
|
||||
|
||||
private StatefulConnection<byte[], byte[]> getOrCreateDedicatedConnection() {
|
||||
|
||||
if (asyncDedicatedConn == null) {
|
||||
@@ -1094,15 +1074,23 @@ public class LettuceConnection extends AbstractRedisConnection {
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
protected StatefulConnection<byte[], byte[]> doGetAsyncDedicatedConnection() {
|
||||
private RedisAsyncCommands<byte[], byte[]> getAsyncDedicatedRedisCommands() {
|
||||
return (RedisAsyncCommands) getAsyncDedicatedConnection();
|
||||
}
|
||||
|
||||
StatefulConnection connection = connectionProvider.getConnection(StatefulConnection.class);
|
||||
|
||||
if (customizedDatabaseIndex()) {
|
||||
potentiallySelectDatabase(dbIndex);
|
||||
private void checkSubscription() {
|
||||
if (isSubscribed()) {
|
||||
throw new RedisSubscribedConnectionException(
|
||||
"Connection already subscribed; use the connection Subscription to cancel or add new channels");
|
||||
}
|
||||
}
|
||||
|
||||
return connection;
|
||||
private LettuceSubscription initSubscription(MessageListener listener) {
|
||||
return doCreateSubscription(listener, switchToPubSub(), connectionProvider);
|
||||
}
|
||||
|
||||
private RedisURI getRedisURI(RedisNode node) {
|
||||
return RedisURI.Builder.redis(node.getHost(), node.getPort()).build();
|
||||
}
|
||||
|
||||
private boolean customizedDatabaseIndex() {
|
||||
@@ -1138,47 +1126,6 @@ public class LettuceConnection extends AbstractRedisConnection {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean isActive(RedisNode node) {
|
||||
|
||||
StatefulRedisSentinelConnection<String, String> connection = null;
|
||||
try {
|
||||
connection = getConnection(node);
|
||||
return connection.sync().ping().equalsIgnoreCase("pong");
|
||||
} catch (Exception e) {
|
||||
return false;
|
||||
} finally {
|
||||
if (connection != null) {
|
||||
connectionProvider.release(connection);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private RedisURI getRedisURI(RedisNode node) {
|
||||
return RedisURI.Builder.redis(node.getHost(), node.getPort()).build();
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.redis.connection.AbstractRedisConnection#getSentinelConnection(org.springframework.data.redis.connection.RedisNode)
|
||||
*/
|
||||
@Override
|
||||
protected RedisSentinelConnection getSentinelConnection(RedisNode sentinel) {
|
||||
|
||||
StatefulRedisSentinelConnection<String, String> connection = getConnection(sentinel);
|
||||
return new LettuceSentinelConnection(connection);
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private StatefulRedisSentinelConnection<String, String> getConnection(RedisNode sentinel) {
|
||||
return ((TargetAware) connectionProvider).getConnection(StatefulRedisSentinelConnection.class,
|
||||
getRedisURI(sentinel));
|
||||
}
|
||||
|
||||
LettuceConnectionProvider getConnectionProvider() {
|
||||
return connectionProvider;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@link TypeHints} provide {@link CommandOutput} information for a given {@link CommandType}.
|
||||
*
|
||||
@@ -1481,7 +1428,7 @@ public class LettuceConnection extends AbstractRedisConnection {
|
||||
|
||||
/**
|
||||
* State object associated with flushing of the currently ongoing pipeline.
|
||||
*
|
||||
*
|
||||
* @author Mark Paluch
|
||||
* @since 2.3
|
||||
*/
|
||||
@@ -1514,7 +1461,7 @@ public class LettuceConnection extends AbstractRedisConnection {
|
||||
|
||||
/**
|
||||
* Implementation to flush on each command.
|
||||
*
|
||||
*
|
||||
* @author Mark Paluch
|
||||
* @since 2.3
|
||||
*/
|
||||
@@ -1539,7 +1486,7 @@ public class LettuceConnection extends AbstractRedisConnection {
|
||||
|
||||
/**
|
||||
* Implementation to flush on closing the pipeline.
|
||||
*
|
||||
*
|
||||
* @author Mark Paluch
|
||||
* @since 2.3
|
||||
*/
|
||||
@@ -1571,7 +1518,7 @@ public class LettuceConnection extends AbstractRedisConnection {
|
||||
|
||||
/**
|
||||
* Pipeline state for buffered flushing.
|
||||
*
|
||||
*
|
||||
* @author Mark Paluch
|
||||
* @since 2.3
|
||||
*/
|
||||
|
||||
@@ -104,7 +104,7 @@ abstract public class LettuceConverters extends Converters {
|
||||
private static final Converter<Partitions, List<RedisClusterNode>> PARTITIONS_TO_CLUSTER_NODES;
|
||||
private static Converter<io.lettuce.core.cluster.models.partitions.RedisClusterNode, RedisClusterNode> CLUSTER_NODE_TO_CLUSTER_NODE_CONVERTER;
|
||||
private static final Converter<List<byte[]>, Long> BYTES_LIST_TO_TIME_CONVERTER;
|
||||
private static final Converter<GeoCoordinates, Point> GEO_COORDINATE_TO_POINT_CONVERTER;
|
||||
public static final Converter<GeoCoordinates, Point> GEO_COORDINATE_TO_POINT_CONVERTER;
|
||||
private static final ListConverter<GeoCoordinates, Point> GEO_COORDINATE_LIST_TO_POINT_LIST_CONVERTER;
|
||||
private static final Converter<KeyValue<Object, Object>, Object> KEY_VALUE_UNWRAPPER;
|
||||
private static final ListConverter<KeyValue<Object, Object>, Object> KEY_VALUE_LIST_UNWRAPPER;
|
||||
|
||||
@@ -16,10 +16,8 @@
|
||||
package org.springframework.data.redis.connection.lettuce;
|
||||
|
||||
import io.lettuce.core.GeoArgs;
|
||||
import io.lettuce.core.GeoCoordinates;
|
||||
import io.lettuce.core.GeoWithin;
|
||||
import io.lettuce.core.cluster.api.async.RedisClusterAsyncCommands;
|
||||
import io.lettuce.core.cluster.api.sync.RedisClusterCommands;
|
||||
import io.lettuce.core.api.async.RedisGeoAsyncCommands;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
@@ -27,18 +25,14 @@ import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import org.springframework.core.convert.converter.Converter;
|
||||
import org.springframework.dao.DataAccessException;
|
||||
import org.springframework.data.geo.Circle;
|
||||
import org.springframework.data.geo.Distance;
|
||||
import org.springframework.data.geo.GeoResults;
|
||||
import org.springframework.data.geo.Metric;
|
||||
import org.springframework.data.geo.Point;
|
||||
import org.springframework.data.redis.connection.NullableResult;
|
||||
import org.springframework.data.redis.connection.RedisGeoCommands;
|
||||
import org.springframework.data.redis.connection.convert.ListConverter;
|
||||
import org.springframework.lang.Nullable;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
@@ -66,19 +60,7 @@ class LettuceGeoCommands implements RedisGeoCommands {
|
||||
Assert.notNull(point, "Point must not be null!");
|
||||
Assert.notNull(member, "Member must not be null!");
|
||||
|
||||
try {
|
||||
if (isPipelined()) {
|
||||
pipeline(connection.newLettuceResult(getAsyncConnection().geoadd(key, point.getX(), point.getY(), member)));
|
||||
return null;
|
||||
}
|
||||
if (isQueueing()) {
|
||||
transaction(connection.newLettuceResult(getAsyncConnection().geoadd(key, point.getX(), point.getY(), member)));
|
||||
return null;
|
||||
}
|
||||
return getConnection().geoadd(key, point.getX(), point.getY(), member);
|
||||
} catch (Exception ex) {
|
||||
throw convertLettuceAccessException(ex);
|
||||
}
|
||||
return connection.invoke().just(RedisGeoAsyncCommands::geoadd, key, point.getX(), point.getY(), member);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -125,21 +107,7 @@ class LettuceGeoCommands implements RedisGeoCommands {
|
||||
|
||||
@Nullable
|
||||
private Long geoAdd(byte[] key, Collection<Object> values) {
|
||||
|
||||
try {
|
||||
|
||||
if (isPipelined()) {
|
||||
pipeline(connection.newLettuceResult(getAsyncConnection().geoadd(key, values.toArray())));
|
||||
return null;
|
||||
}
|
||||
if (isQueueing()) {
|
||||
transaction(connection.newLettuceResult(getAsyncConnection().geoadd(key, values.toArray())));
|
||||
return null;
|
||||
}
|
||||
return getConnection().geoadd(key, values.toArray());
|
||||
} catch (Exception ex) {
|
||||
throw convertLettuceAccessException(ex);
|
||||
}
|
||||
return connection.invoke().just(it -> it.geoadd(key, values.toArray()));
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -166,12 +134,8 @@ class LettuceGeoCommands implements RedisGeoCommands {
|
||||
GeoArgs.Unit geoUnit = LettuceConverters.toGeoArgsUnit(metric);
|
||||
Converter<Double, Distance> distanceConverter = LettuceConverters.distanceConverterForMetric(metric);
|
||||
|
||||
// return connection.execute(
|
||||
// sync -> sync.geodist(key, member1, member2, geoUnit),
|
||||
// async -> async.geodist(key, member1, member2, geoUnit),
|
||||
// distanceConverter);
|
||||
|
||||
return connection.invoke(connection.getAsyncConnection().geodist(key, member1, member2, geoUnit), distanceConverter);
|
||||
return connection.invoke().from(RedisGeoAsyncCommands::geodist, key, member1, member2, geoUnit)
|
||||
.get(distanceConverter);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -185,20 +149,8 @@ class LettuceGeoCommands implements RedisGeoCommands {
|
||||
Assert.notNull(members, "Members must not be null!");
|
||||
Assert.noNullElements(members, "Members must not contain null!");
|
||||
|
||||
try {
|
||||
if (isPipelined()) {
|
||||
pipeline(connection.newLettuceResult(getAsyncConnection().geohash(key, members)));
|
||||
return null;
|
||||
}
|
||||
if (isQueueing()) {
|
||||
transaction(connection.newLettuceResult(getAsyncConnection().geohash(key, members)));
|
||||
return null;
|
||||
}
|
||||
return getConnection().geohash(key, members).stream().map(value -> value.getValueOrElse(null))
|
||||
.collect(Collectors.toList());
|
||||
} catch (Exception ex) {
|
||||
throw convertLettuceAccessException(ex);
|
||||
}
|
||||
return connection.invoke().fromMany(RedisGeoAsyncCommands::geohash, key, members)
|
||||
.toList(it -> it.getValueOrElse(null));
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -212,21 +164,8 @@ class LettuceGeoCommands implements RedisGeoCommands {
|
||||
Assert.notNull(members, "Members must not be null!");
|
||||
Assert.noNullElements(members, "Members must not contain null!");
|
||||
|
||||
ListConverter<GeoCoordinates, Point> converter = LettuceConverters.geoCoordinatesToPointConverter();
|
||||
|
||||
try {
|
||||
if (isPipelined()) {
|
||||
pipeline(connection.newLettuceResult(getAsyncConnection().geopos(key, members), converter));
|
||||
return null;
|
||||
}
|
||||
if (isQueueing()) {
|
||||
transaction(connection.newLettuceResult(getAsyncConnection().geopos(key, members), converter));
|
||||
return null;
|
||||
}
|
||||
return converter.convert(getConnection().geopos(key, members));
|
||||
} catch (Exception ex) {
|
||||
throw convertLettuceAccessException(ex);
|
||||
}
|
||||
return connection.invoke().fromMany(RedisGeoAsyncCommands::geopos, key, members)
|
||||
.toList(LettuceConverters.GEO_COORDINATE_TO_POINT_CONVERTER);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -242,27 +181,10 @@ class LettuceGeoCommands implements RedisGeoCommands {
|
||||
Converter<Set<byte[]>, GeoResults<GeoLocation<byte[]>>> geoResultsConverter = LettuceConverters
|
||||
.bytesSetToGeoResultsConverter();
|
||||
|
||||
try {
|
||||
if (isPipelined()) {
|
||||
pipeline(connection.newLettuceResult(
|
||||
getAsyncConnection().georadius(key, within.getCenter().getX(), within.getCenter().getY(),
|
||||
within.getRadius().getValue(), LettuceConverters.toGeoArgsUnit(within.getRadius().getMetric())),
|
||||
geoResultsConverter));
|
||||
return null;
|
||||
}
|
||||
if (isQueueing()) {
|
||||
transaction(connection.newLettuceResult(
|
||||
getAsyncConnection().georadius(key, within.getCenter().getX(), within.getCenter().getY(),
|
||||
within.getRadius().getValue(), LettuceConverters.toGeoArgsUnit(within.getRadius().getMetric())),
|
||||
geoResultsConverter));
|
||||
return null;
|
||||
}
|
||||
return geoResultsConverter
|
||||
.convert(getConnection().georadius(key, within.getCenter().getX(), within.getCenter().getY(),
|
||||
within.getRadius().getValue(), LettuceConverters.toGeoArgsUnit(within.getRadius().getMetric())));
|
||||
} catch (Exception ex) {
|
||||
throw convertLettuceAccessException(ex);
|
||||
}
|
||||
return connection.invoke()
|
||||
.from(it -> it.georadius(key, within.getCenter().getX(), within.getCenter().getY(),
|
||||
within.getRadius().getValue(), LettuceConverters.toGeoArgsUnit(within.getRadius().getMetric())))
|
||||
.get(geoResultsConverter);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -280,25 +202,10 @@ class LettuceGeoCommands implements RedisGeoCommands {
|
||||
Converter<List<GeoWithin<byte[]>>, GeoResults<GeoLocation<byte[]>>> geoResultsConverter = LettuceConverters
|
||||
.geoRadiusResponseToGeoResultsConverter(within.getRadius().getMetric());
|
||||
|
||||
try {
|
||||
if (isPipelined()) {
|
||||
pipeline(connection.newLettuceResult(getAsyncConnection().georadius(key, within.getCenter().getX(),
|
||||
within.getCenter().getY(), within.getRadius().getValue(),
|
||||
LettuceConverters.toGeoArgsUnit(within.getRadius().getMetric()), geoArgs), geoResultsConverter));
|
||||
return null;
|
||||
}
|
||||
if (isQueueing()) {
|
||||
transaction(connection.newLettuceResult(getAsyncConnection().georadius(key, within.getCenter().getX(),
|
||||
within.getCenter().getY(), within.getRadius().getValue(),
|
||||
LettuceConverters.toGeoArgsUnit(within.getRadius().getMetric()), geoArgs), geoResultsConverter));
|
||||
return null;
|
||||
}
|
||||
return geoResultsConverter
|
||||
.convert(getConnection().georadius(key, within.getCenter().getX(), within.getCenter().getY(),
|
||||
within.getRadius().getValue(), LettuceConverters.toGeoArgsUnit(within.getRadius().getMetric()), geoArgs));
|
||||
} catch (Exception ex) {
|
||||
throw convertLettuceAccessException(ex);
|
||||
}
|
||||
return connection.invoke()
|
||||
.from(it -> it.georadius(key, within.getCenter().getX(), within.getCenter().getY(),
|
||||
within.getRadius().getValue(), LettuceConverters.toGeoArgsUnit(within.getRadius().getMetric()), geoArgs))
|
||||
.get(geoResultsConverter);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -325,21 +232,8 @@ class LettuceGeoCommands implements RedisGeoCommands {
|
||||
Converter<Set<byte[]>, GeoResults<GeoLocation<byte[]>>> converter = LettuceConverters
|
||||
.bytesSetToGeoResultsConverter();
|
||||
|
||||
try {
|
||||
if (isPipelined()) {
|
||||
pipeline(connection.newLettuceResult(
|
||||
getAsyncConnection().georadiusbymember(key, member, radius.getValue(), geoUnit), converter));
|
||||
return null;
|
||||
}
|
||||
if (isQueueing()) {
|
||||
transaction(connection.newLettuceResult(
|
||||
getAsyncConnection().georadiusbymember(key, member, radius.getValue(), geoUnit), converter));
|
||||
return null;
|
||||
}
|
||||
return converter.convert(getConnection().georadiusbymember(key, member, radius.getValue(), geoUnit));
|
||||
} catch (Exception ex) {
|
||||
throw convertLettuceAccessException(ex);
|
||||
}
|
||||
return connection.invoke().from(RedisGeoAsyncCommands::georadiusbymember, key, member, radius.getValue(), geoUnit)
|
||||
.get(converter);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -360,24 +254,9 @@ class LettuceGeoCommands implements RedisGeoCommands {
|
||||
Converter<List<GeoWithin<byte[]>>, GeoResults<GeoLocation<byte[]>>> geoResultsConverter = LettuceConverters
|
||||
.geoRadiusResponseToGeoResultsConverter(radius.getMetric());
|
||||
|
||||
try {
|
||||
if (isPipelined()) {
|
||||
pipeline(connection.newLettuceResult(
|
||||
getAsyncConnection().georadiusbymember(key, member, radius.getValue(), geoUnit, geoArgs),
|
||||
geoResultsConverter));
|
||||
return null;
|
||||
}
|
||||
if (isQueueing()) {
|
||||
transaction(connection.newLettuceResult(
|
||||
getAsyncConnection().georadiusbymember(key, member, radius.getValue(), geoUnit, geoArgs),
|
||||
geoResultsConverter));
|
||||
return null;
|
||||
}
|
||||
return geoResultsConverter
|
||||
.convert(getConnection().georadiusbymember(key, member, radius.getValue(), geoUnit, geoArgs));
|
||||
} catch (Exception ex) {
|
||||
throw convertLettuceAccessException(ex);
|
||||
}
|
||||
return connection.invoke()
|
||||
.from(RedisGeoAsyncCommands::georadiusbymember, key, member, radius.getValue(), geoUnit, geoArgs)
|
||||
.get(geoResultsConverter);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -389,31 +268,4 @@ class LettuceGeoCommands implements RedisGeoCommands {
|
||||
return connection.zSetCommands().zRem(key, values);
|
||||
}
|
||||
|
||||
private boolean isPipelined() {
|
||||
return connection.isPipelined();
|
||||
}
|
||||
|
||||
private boolean isQueueing() {
|
||||
return connection.isQueueing();
|
||||
}
|
||||
|
||||
private void pipeline(LettuceResult result) {
|
||||
connection.pipeline(result);
|
||||
}
|
||||
|
||||
private void transaction(LettuceResult result) {
|
||||
connection.transaction(result);
|
||||
}
|
||||
|
||||
private RedisClusterAsyncCommands<byte[], byte[]> getAsyncConnection() {
|
||||
return connection.getAsyncConnection();
|
||||
}
|
||||
|
||||
public RedisClusterCommands<byte[], byte[]> getConnection() {
|
||||
return connection.getConnection();
|
||||
}
|
||||
|
||||
private DataAccessException convertLettuceAccessException(Exception ex) {
|
||||
return connection.convertLettuceAccessException(ex);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -17,15 +17,13 @@ package org.springframework.data.redis.connection.lettuce;
|
||||
|
||||
import io.lettuce.core.MapScanCursor;
|
||||
import io.lettuce.core.ScanArgs;
|
||||
import io.lettuce.core.cluster.api.async.RedisClusterAsyncCommands;
|
||||
import io.lettuce.core.cluster.api.sync.RedisClusterCommands;
|
||||
import io.lettuce.core.api.async.RedisHashAsyncCommands;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.Set;
|
||||
|
||||
import org.springframework.dao.DataAccessException;
|
||||
import org.springframework.data.redis.connection.RedisHashCommands;
|
||||
import org.springframework.data.redis.core.Cursor;
|
||||
import org.springframework.data.redis.core.KeyBoundCursor;
|
||||
@@ -58,19 +56,7 @@ class LettuceHashCommands implements RedisHashCommands {
|
||||
Assert.notNull(field, "Field must not be null!");
|
||||
Assert.notNull(value, "Value must not be null!");
|
||||
|
||||
try {
|
||||
if (isPipelined()) {
|
||||
pipeline(connection.newLettuceResult(getAsyncConnection().hset(key, field, value)));
|
||||
return null;
|
||||
}
|
||||
if (isQueueing()) {
|
||||
transaction(connection.newLettuceResult(getAsyncConnection().hset(key, field, value)));
|
||||
return null;
|
||||
}
|
||||
return getConnection().hset(key, field, value);
|
||||
} catch (Exception ex) {
|
||||
throw convertLettuceAccessException(ex);
|
||||
}
|
||||
return connection.invoke().just(RedisHashAsyncCommands::hset, key, field, value);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -84,19 +70,7 @@ class LettuceHashCommands implements RedisHashCommands {
|
||||
Assert.notNull(field, "Field must not be null!");
|
||||
Assert.notNull(value, "Value must not be null!");
|
||||
|
||||
try {
|
||||
if (isPipelined()) {
|
||||
pipeline(connection.newLettuceResult(getAsyncConnection().hsetnx(key, field, value)));
|
||||
return null;
|
||||
}
|
||||
if (isQueueing()) {
|
||||
transaction(connection.newLettuceResult(getAsyncConnection().hsetnx(key, field, value)));
|
||||
return null;
|
||||
}
|
||||
return getConnection().hsetnx(key, field, value);
|
||||
} catch (Exception ex) {
|
||||
throw convertLettuceAccessException(ex);
|
||||
}
|
||||
return connection.invoke().just(RedisHashAsyncCommands::hsetnx, key, field, value);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -109,19 +83,7 @@ class LettuceHashCommands implements RedisHashCommands {
|
||||
Assert.notNull(key, "Key must not be null!");
|
||||
Assert.notNull(fields, "Fields must not be null!");
|
||||
|
||||
try {
|
||||
if (isPipelined()) {
|
||||
pipeline(connection.newLettuceResult(getAsyncConnection().hdel(key, fields)));
|
||||
return null;
|
||||
}
|
||||
if (isQueueing()) {
|
||||
transaction(connection.newLettuceResult(getAsyncConnection().hdel(key, fields)));
|
||||
return null;
|
||||
}
|
||||
return getConnection().hdel(key, fields);
|
||||
} catch (Exception ex) {
|
||||
throw convertLettuceAccessException(ex);
|
||||
}
|
||||
return connection.invoke().just(RedisHashAsyncCommands::hdel, key, fields);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -134,19 +96,7 @@ class LettuceHashCommands implements RedisHashCommands {
|
||||
Assert.notNull(key, "Key must not be null!");
|
||||
Assert.notNull(field, "Fields must not be null!");
|
||||
|
||||
try {
|
||||
if (isPipelined()) {
|
||||
pipeline(connection.newLettuceResult(getAsyncConnection().hexists(key, field)));
|
||||
return null;
|
||||
}
|
||||
if (isQueueing()) {
|
||||
transaction(connection.newLettuceResult(getAsyncConnection().hexists(key, field)));
|
||||
return null;
|
||||
}
|
||||
return getConnection().hexists(key, field);
|
||||
} catch (Exception ex) {
|
||||
throw convertLettuceAccessException(ex);
|
||||
}
|
||||
return connection.invoke().just(RedisHashAsyncCommands::hexists, key, field);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -159,19 +109,7 @@ class LettuceHashCommands implements RedisHashCommands {
|
||||
Assert.notNull(key, "Key must not be null!");
|
||||
Assert.notNull(field, "Field must not be null!");
|
||||
|
||||
try {
|
||||
if (isPipelined()) {
|
||||
pipeline(connection.newLettuceResult(getAsyncConnection().hget(key, field)));
|
||||
return null;
|
||||
}
|
||||
if (isQueueing()) {
|
||||
transaction(connection.newLettuceResult(getAsyncConnection().hget(key, field)));
|
||||
return null;
|
||||
}
|
||||
return getConnection().hget(key, field);
|
||||
} catch (Exception ex) {
|
||||
throw convertLettuceAccessException(ex);
|
||||
}
|
||||
return connection.invoke().just(RedisHashAsyncCommands::hget, key, field);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -183,19 +121,7 @@ class LettuceHashCommands implements RedisHashCommands {
|
||||
|
||||
Assert.notNull(key, "Key must not be null!");
|
||||
|
||||
try {
|
||||
if (isPipelined()) {
|
||||
pipeline(connection.newLettuceResult(getAsyncConnection().hgetall(key)));
|
||||
return null;
|
||||
}
|
||||
if (isQueueing()) {
|
||||
transaction(connection.newLettuceResult(getAsyncConnection().hgetall(key)));
|
||||
return null;
|
||||
}
|
||||
return getConnection().hgetall(key);
|
||||
} catch (Exception ex) {
|
||||
throw convertLettuceAccessException(ex);
|
||||
}
|
||||
return connection.invoke().just(RedisHashAsyncCommands::hgetall, key);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -208,19 +134,7 @@ class LettuceHashCommands implements RedisHashCommands {
|
||||
Assert.notNull(key, "Key must not be null!");
|
||||
Assert.notNull(field, "Field must not be null!");
|
||||
|
||||
try {
|
||||
if (isPipelined()) {
|
||||
pipeline(connection.newLettuceResult(getAsyncConnection().hincrby(key, field, delta)));
|
||||
return null;
|
||||
}
|
||||
if (isQueueing()) {
|
||||
transaction(connection.newLettuceResult(getAsyncConnection().hincrby(key, field, delta)));
|
||||
return null;
|
||||
}
|
||||
return getConnection().hincrby(key, field, delta);
|
||||
} catch (Exception ex) {
|
||||
throw convertLettuceAccessException(ex);
|
||||
}
|
||||
return connection.invoke().just(RedisHashAsyncCommands::hincrby, key, field, delta);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -233,19 +147,7 @@ class LettuceHashCommands implements RedisHashCommands {
|
||||
Assert.notNull(key, "Key must not be null!");
|
||||
Assert.notNull(field, "Field must not be null!");
|
||||
|
||||
try {
|
||||
if (isPipelined()) {
|
||||
pipeline(connection.newLettuceResult(getAsyncConnection().hincrbyfloat(key, field, delta)));
|
||||
return null;
|
||||
}
|
||||
if (isQueueing()) {
|
||||
transaction(connection.newLettuceResult(getAsyncConnection().hincrbyfloat(key, field, delta)));
|
||||
return null;
|
||||
}
|
||||
return getConnection().hincrbyfloat(key, field, delta);
|
||||
} catch (Exception ex) {
|
||||
throw convertLettuceAccessException(ex);
|
||||
}
|
||||
return connection.invoke().just(RedisHashAsyncCommands::hincrbyfloat, key, field, delta);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -257,20 +159,7 @@ class LettuceHashCommands implements RedisHashCommands {
|
||||
|
||||
Assert.notNull(key, "Key must not be null!");
|
||||
|
||||
try {
|
||||
if (isPipelined()) {
|
||||
pipeline(connection.newLettuceResult(getAsyncConnection().hkeys(key), LettuceConverters.bytesListToBytesSet()));
|
||||
return null;
|
||||
}
|
||||
if (isQueueing()) {
|
||||
transaction(
|
||||
connection.newLettuceResult(getAsyncConnection().hkeys(key), LettuceConverters.bytesListToBytesSet()));
|
||||
return null;
|
||||
}
|
||||
return LettuceConverters.toBytesSet(getConnection().hkeys(key));
|
||||
} catch (Exception ex) {
|
||||
throw convertLettuceAccessException(ex);
|
||||
}
|
||||
return connection.invoke().from(RedisHashAsyncCommands::hkeys, key).get(LettuceConverters.bytesListToBytesSet());
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -282,19 +171,7 @@ class LettuceHashCommands implements RedisHashCommands {
|
||||
|
||||
Assert.notNull(key, "Key must not be null!");
|
||||
|
||||
try {
|
||||
if (isPipelined()) {
|
||||
pipeline(connection.newLettuceResult(getAsyncConnection().hlen(key)));
|
||||
return null;
|
||||
}
|
||||
if (isQueueing()) {
|
||||
transaction(connection.newLettuceResult(getAsyncConnection().hlen(key)));
|
||||
return null;
|
||||
}
|
||||
return getConnection().hlen(key);
|
||||
} catch (Exception ex) {
|
||||
throw convertLettuceAccessException(ex);
|
||||
}
|
||||
return connection.invoke().just(RedisHashAsyncCommands::hlen, key);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -307,21 +184,8 @@ class LettuceHashCommands implements RedisHashCommands {
|
||||
Assert.notNull(key, "Key must not be null!");
|
||||
Assert.notNull(fields, "Fields must not be null!");
|
||||
|
||||
try {
|
||||
if (isPipelined()) {
|
||||
pipeline(connection.newLettuceResult(getAsyncConnection().hmget(key, fields),
|
||||
LettuceConverters.keyValueListUnwrapper()));
|
||||
return null;
|
||||
}
|
||||
if (isQueueing()) {
|
||||
transaction(connection.newLettuceResult(getAsyncConnection().hmget(key, fields),
|
||||
LettuceConverters.keyValueListUnwrapper()));
|
||||
return null;
|
||||
}
|
||||
return LettuceConverters.<byte[], byte[]> keyValueListUnwrapper().convert(getConnection().hmget(key, fields));
|
||||
} catch (Exception ex) {
|
||||
throw convertLettuceAccessException(ex);
|
||||
}
|
||||
return connection.invoke().fromMany(RedisHashAsyncCommands::hmget, key, fields)
|
||||
.toList(source -> source.getValueOrElse(null));
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -334,19 +198,7 @@ class LettuceHashCommands implements RedisHashCommands {
|
||||
Assert.notNull(key, "Key must not be null!");
|
||||
Assert.notNull(hashes, "Hashes must not be null!");
|
||||
|
||||
try {
|
||||
if (isPipelined()) {
|
||||
pipeline(connection.newLettuceStatusResult(getAsyncConnection().hmset(key, hashes)));
|
||||
return;
|
||||
}
|
||||
if (isQueueing()) {
|
||||
transaction(connection.newLettuceStatusResult(getAsyncConnection().hmset(key, hashes)));
|
||||
return;
|
||||
}
|
||||
getConnection().hmset(key, hashes);
|
||||
} catch (Exception ex) {
|
||||
throw convertLettuceAccessException(ex);
|
||||
}
|
||||
connection.invokeStatus().just(RedisHashAsyncCommands::hmset, key, hashes);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -358,22 +210,11 @@ class LettuceHashCommands implements RedisHashCommands {
|
||||
|
||||
Assert.notNull(key, "Key must not be null!");
|
||||
|
||||
try {
|
||||
if (isPipelined()) {
|
||||
pipeline(connection.newLettuceResult(getAsyncConnection().hvals(key)));
|
||||
return null;
|
||||
}
|
||||
if (isQueueing()) {
|
||||
transaction(connection.newLettuceResult(getAsyncConnection().hvals(key)));
|
||||
return null;
|
||||
}
|
||||
return getConnection().hvals(key);
|
||||
} catch (Exception ex) {
|
||||
throw convertLettuceAccessException(ex);
|
||||
}
|
||||
return connection.invoke().just(RedisHashAsyncCommands::hvals, key);
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.redis.connection.RedisHashCommands#hScan(byte[], org.springframework.data.redis.core.ScanOptions)
|
||||
*/
|
||||
@Override
|
||||
@@ -397,14 +238,15 @@ class LettuceHashCommands implements RedisHashCommands {
|
||||
@Override
|
||||
protected ScanIteration<Entry<byte[], byte[]>> doScan(byte[] key, long cursorId, ScanOptions options) {
|
||||
|
||||
if (isQueueing() || isPipelined()) {
|
||||
if (connection.isQueueing() || connection.isPipelined()) {
|
||||
throw new UnsupportedOperationException("'HSCAN' cannot be called in pipeline / transaction mode.");
|
||||
}
|
||||
|
||||
io.lettuce.core.ScanCursor scanCursor = connection.getScanCursor(cursorId);
|
||||
ScanArgs scanArgs = LettuceConverters.toScanArgs(options);
|
||||
|
||||
MapScanCursor<byte[], byte[]> mapScanCursor = getConnection().hscan(key, scanCursor, scanArgs);
|
||||
MapScanCursor<byte[], byte[]> mapScanCursor = connection.invoke().just(RedisHashAsyncCommands::hscan, key,
|
||||
scanCursor, scanArgs);
|
||||
String nextCursorId = mapScanCursor.getCursor();
|
||||
|
||||
Map<byte[], byte[]> values = mapScanCursor.getMap();
|
||||
@@ -429,47 +271,8 @@ class LettuceHashCommands implements RedisHashCommands {
|
||||
|
||||
Assert.notNull(key, "Key must not be null!");
|
||||
Assert.notNull(field, "Field must not be null!");
|
||||
try {
|
||||
if (isPipelined()) {
|
||||
pipeline(connection.newLettuceResult(getAsyncConnection().hstrlen(key, field)));
|
||||
return null;
|
||||
}
|
||||
if (isQueueing()) {
|
||||
transaction(connection.newLettuceResult(getAsyncConnection().hstrlen(key, field)));
|
||||
return null;
|
||||
}
|
||||
return getConnection().hstrlen(key, field);
|
||||
} catch (Exception ex) {
|
||||
throw convertLettuceAccessException(ex);
|
||||
}
|
||||
}
|
||||
|
||||
private boolean isPipelined() {
|
||||
return connection.isPipelined();
|
||||
}
|
||||
|
||||
private boolean isQueueing() {
|
||||
return connection.isQueueing();
|
||||
}
|
||||
|
||||
private void pipeline(LettuceResult result) {
|
||||
connection.pipeline(result);
|
||||
}
|
||||
|
||||
private void transaction(LettuceResult result) {
|
||||
connection.transaction(result);
|
||||
}
|
||||
|
||||
private RedisClusterAsyncCommands<byte[], byte[]> getAsyncConnection() {
|
||||
return connection.getAsyncConnection();
|
||||
}
|
||||
|
||||
public RedisClusterCommands<byte[], byte[]> getConnection() {
|
||||
return connection.getConnection();
|
||||
}
|
||||
|
||||
private DataAccessException convertLettuceAccessException(Exception ex) {
|
||||
return connection.convertLettuceAccessException(ex);
|
||||
return connection.invoke().just(RedisHashAsyncCommands::hstrlen, key, field);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -15,11 +15,8 @@
|
||||
*/
|
||||
package org.springframework.data.redis.connection.lettuce;
|
||||
|
||||
import io.lettuce.core.api.sync.RedisHLLCommands;
|
||||
import io.lettuce.core.cluster.api.async.RedisClusterAsyncCommands;
|
||||
import io.lettuce.core.cluster.api.sync.RedisClusterCommands;
|
||||
import io.lettuce.core.api.async.RedisHLLAsyncCommands;
|
||||
|
||||
import org.springframework.dao.DataAccessException;
|
||||
import org.springframework.data.redis.connection.RedisHyperLogLogCommands;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
@@ -46,22 +43,7 @@ class LettuceHyperLogLogCommands implements RedisHyperLogLogCommands {
|
||||
Assert.notEmpty(values, "PFADD requires at least one non 'null' value.");
|
||||
Assert.noNullElements(values, "Values for PFADD must not contain 'null'.");
|
||||
|
||||
try {
|
||||
if (isPipelined()) {
|
||||
pipeline(connection.newLettuceResult(getAsyncConnection().pfadd(key, values)));
|
||||
return null;
|
||||
}
|
||||
|
||||
if (isQueueing()) {
|
||||
transaction(connection.newLettuceResult(getAsyncConnection().pfadd(key, values)));
|
||||
return null;
|
||||
}
|
||||
|
||||
RedisHLLCommands<byte[], byte[]> connection = getConnection();
|
||||
return connection.pfadd(key, values);
|
||||
} catch (Exception ex) {
|
||||
throw convertLettuceAccessException(ex);
|
||||
}
|
||||
return connection.invoke().just(RedisHLLAsyncCommands::pfadd, key, values);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -74,22 +56,7 @@ class LettuceHyperLogLogCommands implements RedisHyperLogLogCommands {
|
||||
Assert.notEmpty(keys, "PFCOUNT requires at least one non 'null' key.");
|
||||
Assert.noNullElements(keys, "Keys for PFCOUNT must not contain 'null'.");
|
||||
|
||||
try {
|
||||
if (isPipelined()) {
|
||||
pipeline(connection.newLettuceResult(getAsyncConnection().pfcount(keys)));
|
||||
return null;
|
||||
}
|
||||
|
||||
if (isQueueing()) {
|
||||
transaction(connection.newLettuceResult(getAsyncConnection().pfcount(keys)));
|
||||
return null;
|
||||
}
|
||||
|
||||
RedisHLLCommands<byte[], byte[]> connection = getConnection();
|
||||
return connection.pfcount(keys);
|
||||
} catch (Exception ex) {
|
||||
throw convertLettuceAccessException(ex);
|
||||
}
|
||||
return connection.invoke().just(RedisHLLAsyncCommands::pfcount, keys);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -103,49 +70,6 @@ class LettuceHyperLogLogCommands implements RedisHyperLogLogCommands {
|
||||
Assert.notNull(sourceKeys, "Source keys must not be null");
|
||||
Assert.noNullElements(sourceKeys, "Keys for PFMERGE must not contain 'null'.");
|
||||
|
||||
try {
|
||||
if (isPipelined()) {
|
||||
pipeline(connection.newLettuceResult(getAsyncConnection().pfmerge(destinationKey, sourceKeys)));
|
||||
return;
|
||||
}
|
||||
|
||||
if (isQueueing()) {
|
||||
transaction(connection.newLettuceResult(getAsyncConnection().pfmerge(destinationKey, sourceKeys)));
|
||||
return;
|
||||
}
|
||||
|
||||
RedisHLLCommands<byte[], byte[]> connection = getConnection();
|
||||
connection.pfmerge(destinationKey, sourceKeys);
|
||||
} catch (Exception ex) {
|
||||
throw convertLettuceAccessException(ex);
|
||||
}
|
||||
}
|
||||
|
||||
private boolean isPipelined() {
|
||||
return connection.isPipelined();
|
||||
}
|
||||
|
||||
private boolean isQueueing() {
|
||||
return connection.isQueueing();
|
||||
}
|
||||
|
||||
private void pipeline(LettuceResult result) {
|
||||
connection.pipeline(result);
|
||||
}
|
||||
|
||||
private void transaction(LettuceResult result) {
|
||||
connection.transaction(result);
|
||||
}
|
||||
|
||||
private RedisClusterAsyncCommands<byte[], byte[]> getAsyncConnection() {
|
||||
return connection.getAsyncConnection();
|
||||
}
|
||||
|
||||
public RedisClusterCommands<byte[], byte[]> getConnection() {
|
||||
return connection.getConnection();
|
||||
}
|
||||
|
||||
protected DataAccessException convertLettuceAccessException(Exception ex) {
|
||||
return connection.convertLettuceAccessException(ex);
|
||||
connection.invoke().just(RedisHLLAsyncCommands::pfmerge, destinationKey, sourceKeys);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,665 @@
|
||||
/*
|
||||
* Copyright 2021 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.data.redis.connection.lettuce;
|
||||
|
||||
import io.lettuce.core.RedisFuture;
|
||||
import io.lettuce.core.cluster.api.async.RedisClusterAsyncCommands;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
import org.springframework.core.convert.converter.Converter;
|
||||
import org.springframework.lang.Nullable;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
/**
|
||||
* Utility for functional invocation of {@link RedisClusterAsyncCommands Lettuce methods}. Typically used to express the
|
||||
* method call as method reference and passing method arguments through one of the {@code just} or {@code from} methods.
|
||||
* <p>
|
||||
* {@code just} methods record the method call and evaluate the method result immediately. {@code from} methods allows
|
||||
* composing a functional pipeline to transform the result using a {@link Converter}.
|
||||
* <p>
|
||||
* Usage example:
|
||||
*
|
||||
* <pre class="code">
|
||||
* LettuceInvoker invoker = …;
|
||||
*
|
||||
* Long result = invoker.just(RedisGeoAsyncCommands::geoadd, key, point.getX(), point.getY(), member);
|
||||
*
|
||||
* List<byte[]> result = invoker.fromMany(RedisGeoAsyncCommands::geohash, key, members)
|
||||
* .toList(it -> it.getValueOrElse(null));
|
||||
* </pre>
|
||||
* <p>
|
||||
* The actual translation from {@link RedisFuture} is delegated to {@link Synchronizer} which can either await
|
||||
* completion or record the future along {@link Converter} for further processing.
|
||||
*
|
||||
* @author Mark Paluch
|
||||
* @since 2.5
|
||||
*/
|
||||
class LettuceInvoker {
|
||||
|
||||
private final RedisClusterAsyncCommands<byte[], byte[]> connection;
|
||||
private final Synchronizer synchronizer;
|
||||
|
||||
LettuceInvoker(RedisClusterAsyncCommands<byte[], byte[]> connection, Synchronizer synchronizer) {
|
||||
this.connection = connection;
|
||||
this.synchronizer = synchronizer;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a {@link Converter} that always returns its input argument.
|
||||
*
|
||||
* @param <T> the type of the input and output objects to the function
|
||||
* @return a function that always returns its input argument
|
||||
*/
|
||||
static <T> Converter<T, T> identityConverter() {
|
||||
return t -> t;
|
||||
}
|
||||
|
||||
/**
|
||||
* Invoke the {@link ConnectionFunction0} and return its result.
|
||||
*
|
||||
* @param function must not be {@literal null}.
|
||||
*/
|
||||
@Nullable
|
||||
<R> R just(ConnectionFunction0<R> function) {
|
||||
|
||||
Assert.notNull(function, "ConnectionFunction must not be null");
|
||||
|
||||
return synchronizer.invoke(() -> function.apply(connection), identityConverter(), () -> null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Invoke the {@link ConnectionFunction1} and return its result.
|
||||
*
|
||||
* @param function must not be {@literal null}.
|
||||
*/
|
||||
@Nullable
|
||||
<R, T1> R just(ConnectionFunction1<T1, R> function, T1 t1) {
|
||||
|
||||
Assert.notNull(function, "ConnectionFunction must not be null");
|
||||
|
||||
return synchronizer.invoke(() -> function.apply(connection, t1));
|
||||
}
|
||||
|
||||
/**
|
||||
* Invoke the {@link ConnectionFunction2} and return its result.
|
||||
*
|
||||
* @param function must not be {@literal null}.
|
||||
*/
|
||||
@Nullable
|
||||
<R, T1, T2> R just(ConnectionFunction2<T1, T2, R> function, T1 t1, T2 t2) {
|
||||
|
||||
Assert.notNull(function, "ConnectionFunction must not be null");
|
||||
|
||||
return synchronizer.invoke(() -> function.apply(connection, t1, t2));
|
||||
}
|
||||
|
||||
/**
|
||||
* Invoke the {@link ConnectionFunction3} and return its result.
|
||||
*
|
||||
* @param function must not be {@literal null}.
|
||||
*/
|
||||
@Nullable
|
||||
<R, T1, T2, T3> R just(ConnectionFunction3<T1, T2, T3, R> function, T1 t1, T2 t2, T3 t3) {
|
||||
|
||||
Assert.notNull(function, "ConnectionFunction must not be null");
|
||||
|
||||
return synchronizer.invoke(() -> function.apply(connection, t1, t2, t3));
|
||||
}
|
||||
|
||||
/**
|
||||
* Invoke the {@link ConnectionFunction4} and return its result.
|
||||
*
|
||||
* @param function must not be {@literal null}.
|
||||
*/
|
||||
@Nullable
|
||||
<R, T1, T2, T3, T4> R just(ConnectionFunction4<T1, T2, T3, T4, R> function, T1 t1, T2 t2, T3 t3, T4 t4) {
|
||||
|
||||
Assert.notNull(function, "ConnectionFunction must not be null");
|
||||
|
||||
return synchronizer.invoke(() -> function.apply(connection, t1, t2, t3, t4));
|
||||
}
|
||||
|
||||
/**
|
||||
* Invoke the {@link ConnectionFunction5} and return its result.
|
||||
*
|
||||
* @param function must not be {@literal null}.
|
||||
*/
|
||||
@Nullable
|
||||
<R, T1, T2, T3, T4, T5> R just(ConnectionFunction5<T1, T2, T3, T4, T5, R> function, T1 t1, T2 t2, T3 t3, T4 t4,
|
||||
T5 t5) {
|
||||
Assert.notNull(function, "ConnectionFunction must not be null");
|
||||
|
||||
return synchronizer.invoke(() -> function.apply(connection, t1, t2, t3, t4, t5));
|
||||
}
|
||||
|
||||
/**
|
||||
* Compose a invocation pipeline from the {@link ConnectionFunction0} and return a {@link SingleInvocationSpec} for
|
||||
* further composition.
|
||||
*
|
||||
* @param function must not be {@literal null}.
|
||||
*/
|
||||
<R> SingleInvocationSpec<R> from(ConnectionFunction0<R> function) {
|
||||
|
||||
Assert.notNull(function, "ConnectionFunction must not be null");
|
||||
|
||||
return new DefaultSingleInvocationSpec<>(() -> function.apply(connection), synchronizer);
|
||||
}
|
||||
|
||||
/**
|
||||
* Compose a invocation pipeline from the {@link ConnectionFunction1} and return a {@link SingleInvocationSpec} for
|
||||
* further composition.
|
||||
*
|
||||
* @param function must not be {@literal null}.
|
||||
*/
|
||||
<R, T1> SingleInvocationSpec<R> from(ConnectionFunction1<T1, R> function, T1 t1) {
|
||||
|
||||
Assert.notNull(function, "ConnectionFunction must not be null");
|
||||
|
||||
return from(it -> function.apply(it, t1));
|
||||
}
|
||||
|
||||
/**
|
||||
* Compose a invocation pipeline from the {@link ConnectionFunction2} and return a {@link SingleInvocationSpec} for
|
||||
* further composition.
|
||||
*
|
||||
* @param function must not be {@literal null}.
|
||||
*/
|
||||
<R, T1, T2> SingleInvocationSpec<R> from(ConnectionFunction2<T1, T2, R> function, T1 t1, T2 t2) {
|
||||
|
||||
Assert.notNull(function, "ConnectionFunction must not be null");
|
||||
|
||||
return from(it -> function.apply(it, t1, t2));
|
||||
}
|
||||
|
||||
/**
|
||||
* Compose a invocation pipeline from the {@link ConnectionFunction3} and return a {@link SingleInvocationSpec} for
|
||||
* further composition.
|
||||
*
|
||||
* @param function must not be {@literal null}.
|
||||
*/
|
||||
<R, T1, T2, T3> SingleInvocationSpec<R> from(ConnectionFunction3<T1, T2, T3, R> function, T1 t1, T2 t2, T3 t3) {
|
||||
|
||||
Assert.notNull(function, "ConnectionFunction must not be null");
|
||||
|
||||
return from(it -> function.apply(it, t1, t2, t3));
|
||||
}
|
||||
|
||||
/**
|
||||
* Compose a invocation pipeline from the {@link ConnectionFunction4} and return a {@link SingleInvocationSpec} for
|
||||
* further composition.
|
||||
*
|
||||
* @param function must not be {@literal null}.
|
||||
*/
|
||||
<R, T1, T2, T3, T4> SingleInvocationSpec<R> from(ConnectionFunction4<T1, T2, T3, T4, R> function, T1 t1, T2 t2, T3 t3,
|
||||
T4 t4) {
|
||||
|
||||
Assert.notNull(function, "ConnectionFunction must not be null");
|
||||
|
||||
return from(it -> function.apply(it, t1, t2, t3, t4));
|
||||
}
|
||||
|
||||
/**
|
||||
* Compose a invocation pipeline from the {@link ConnectionFunction5} and return a {@link SingleInvocationSpec} for
|
||||
* further composition.
|
||||
*
|
||||
* @param function must not be {@literal null}.
|
||||
*/
|
||||
<R, T1, T2, T3, T4, T5> SingleInvocationSpec<R> from(ConnectionFunction5<T1, T2, T3, T4, T5, R> function, T1 t1,
|
||||
T2 t2, T3 t3, T4 t4, T5 t5) {
|
||||
|
||||
Assert.notNull(function, "ConnectionFunction must not be null");
|
||||
|
||||
return from(it -> function.apply(it, t1, t2, t3, t4, t5));
|
||||
}
|
||||
|
||||
/**
|
||||
* Compose a invocation pipeline from the {@link ConnectionFunction0} that returns a {@link Collection}-like result
|
||||
* and return a {@link ManyInvocationSpec} for further composition.
|
||||
*
|
||||
* @param function must not be {@literal null}.
|
||||
*/
|
||||
<R extends Collection<E>, E> ManyInvocationSpec<E> fromMany(ConnectionFunction0<R> function) {
|
||||
|
||||
Assert.notNull(function, "ConnectionFunction must not be null");
|
||||
|
||||
return new DefaultManyInvocationSpec<>(() -> function.apply(connection), synchronizer);
|
||||
}
|
||||
|
||||
/**
|
||||
* Compose a invocation pipeline from the {@link ConnectionFunction1} that returns a {@link Collection}-like result
|
||||
* and return a {@link ManyInvocationSpec} for further composition.
|
||||
*
|
||||
* @param function must not be {@literal null}.
|
||||
*/
|
||||
<R extends Collection<E>, E, T1> ManyInvocationSpec<E> fromMany(ConnectionFunction1<T1, R> function, T1 t1) {
|
||||
|
||||
Assert.notNull(function, "ConnectionFunction must not be null");
|
||||
|
||||
return fromMany(it -> function.apply(it, t1));
|
||||
}
|
||||
|
||||
/**
|
||||
* Compose a invocation pipeline from the {@link ConnectionFunction2} that returns a {@link Collection}-like result
|
||||
* and return a {@link ManyInvocationSpec} for further composition.
|
||||
*
|
||||
* @param function must not be {@literal null}.
|
||||
*/
|
||||
<R extends Collection<E>, E, T1, T2> ManyInvocationSpec<E> fromMany(ConnectionFunction2<T1, T2, R> function, T1 t1,
|
||||
T2 t2) {
|
||||
|
||||
Assert.notNull(function, "ConnectionFunction must not be null");
|
||||
|
||||
return fromMany(it -> function.apply(it, t1, t2));
|
||||
}
|
||||
|
||||
/**
|
||||
* Compose a invocation pipeline from the {@link ConnectionFunction3} that returns a {@link Collection}-like result
|
||||
* and return a {@link ManyInvocationSpec} for further composition.
|
||||
*
|
||||
* @param function must not be {@literal null}.
|
||||
*/
|
||||
<R extends Collection<E>, E, T1, T2, T3> ManyInvocationSpec<E> fromMany(ConnectionFunction3<T1, T2, T3, R> function,
|
||||
T1 t1, T2 t2, T3 t3) {
|
||||
|
||||
Assert.notNull(function, "ConnectionFunction must not be null");
|
||||
|
||||
return fromMany(it -> function.apply(it, t1, t2, t3));
|
||||
}
|
||||
|
||||
/**
|
||||
* Compose a invocation pipeline from the {@link ConnectionFunction4} that returns a {@link Collection}-like result
|
||||
* and return a {@link ManyInvocationSpec} for further composition.
|
||||
*
|
||||
* @param function must not be {@literal null}.
|
||||
*/
|
||||
<R extends Collection<E>, E, T1, T2, T3, T4> ManyInvocationSpec<E> fromMany(
|
||||
ConnectionFunction4<T1, T2, T3, T4, R> function, T1 t1, T2 t2, T3 t3, T4 t4) {
|
||||
|
||||
Assert.notNull(function, "ConnectionFunction must not be null");
|
||||
|
||||
return fromMany(it -> function.apply(it, t1, t2, t3, t4));
|
||||
}
|
||||
|
||||
/**
|
||||
* Compose a invocation pipeline from the {@link ConnectionFunction5} that returns a {@link Collection}-like result
|
||||
* and return a {@link ManyInvocationSpec} for further composition.
|
||||
*
|
||||
* @param function must not be {@literal null}.
|
||||
*/
|
||||
<R extends Collection<E>, E, T1, T2, T3, T4, T5> ManyInvocationSpec<E> fromMany(
|
||||
ConnectionFunction5<T1, T2, T3, T4, T5, R> function, T1 t1, T2 t2, T3 t3, T4 t4, T5 t5) {
|
||||
|
||||
Assert.notNull(function, "ConnectionFunction must not be null");
|
||||
|
||||
return fromMany(it -> function.apply(it, t1, t2, t3, t4, t5));
|
||||
}
|
||||
|
||||
/**
|
||||
* Represents an element in the invocation pipleline allowing consuming the result by applying a {@link Converter}.
|
||||
*
|
||||
* @param <S>
|
||||
*/
|
||||
public interface SingleInvocationSpec<S> {
|
||||
|
||||
/**
|
||||
* Materialize the pipeline by invoking the {@code ConnectionFunction} and returning the result after applying
|
||||
* {@link Converter}.
|
||||
*
|
||||
* @param converter must not be {@literal null}.
|
||||
* @param <T> target type.
|
||||
* @return the converted result, can be {@literal null}.
|
||||
*/
|
||||
@Nullable
|
||||
<T> T get(Converter<S, T> converter);
|
||||
|
||||
/**
|
||||
* Materialize the pipeline by invoking the {@code ConnectionFunction} and returning the result after applying
|
||||
* {@link Converter}.
|
||||
*
|
||||
* @param converter must not be {@literal null}.
|
||||
* @param nullDefault must not be {@literal null}.
|
||||
* @param <T> target type.
|
||||
* @return the converted result, can be {@literal null}.
|
||||
*/
|
||||
@Nullable
|
||||
<T> T getOrElse(Converter<S, T> converter, Supplier<T> nullDefault);
|
||||
}
|
||||
|
||||
/**
|
||||
* Represents an element in the invocation pipleline for methods returning {@link Collection}-like results allowing
|
||||
* consuming the result by applying a {@link Converter}.
|
||||
*
|
||||
* @param <S>
|
||||
*/
|
||||
public interface ManyInvocationSpec<S> {
|
||||
|
||||
/**
|
||||
* Materialize the pipeline by invoking the {@code ConnectionFunction} and returning the result.
|
||||
*
|
||||
* @return the result as {@link List}.
|
||||
*/
|
||||
default List<S> toList() {
|
||||
return toList(identityConverter());
|
||||
}
|
||||
|
||||
/**
|
||||
* Materialize the pipeline by invoking the {@code ConnectionFunction} and returning the result after applying
|
||||
* {@link Converter}.
|
||||
*
|
||||
* @param converter must not be {@literal null}.
|
||||
* @param <T> target type.
|
||||
* @return the converted {@link List}.
|
||||
*/
|
||||
<T> List<T> toList(Converter<S, T> converter);
|
||||
|
||||
/**
|
||||
* Materialize the pipeline by invoking the {@code ConnectionFunction} and returning the result.
|
||||
*
|
||||
* @return the result as {@link Set}.
|
||||
*/
|
||||
default Set<S> toSet() {
|
||||
return toSet(identityConverter());
|
||||
}
|
||||
|
||||
/**
|
||||
* Materialize the pipeline by invoking the {@code ConnectionFunction} and returning the result after applying
|
||||
* {@link Converter}.
|
||||
*
|
||||
* @param converter must not be {@literal null}.
|
||||
* @param <T> target type.
|
||||
* @return the converted {@link Set}.
|
||||
*/
|
||||
<T> Set<T> toSet(Converter<S, T> converter);
|
||||
}
|
||||
|
||||
/**
|
||||
* A function accepting {@link RedisClusterAsyncCommands} with 0 arguments.
|
||||
*
|
||||
* @param <R>
|
||||
*/
|
||||
@FunctionalInterface
|
||||
public interface ConnectionFunction0<R> {
|
||||
|
||||
/**
|
||||
* Apply this function to the arguments and return a {@link RedisFuture}.
|
||||
*/
|
||||
RedisFuture<R> apply(RedisClusterAsyncCommands<byte[], byte[]> connection);
|
||||
}
|
||||
|
||||
/**
|
||||
* A function accepting {@link RedisClusterAsyncCommands} with 1 argument.
|
||||
*
|
||||
* @param <T1>
|
||||
* @param <R>
|
||||
*/
|
||||
@FunctionalInterface
|
||||
public interface ConnectionFunction1<T1, R> {
|
||||
|
||||
/**
|
||||
* Apply this function to the arguments and return a {@link RedisFuture}.
|
||||
*/
|
||||
RedisFuture<R> apply(RedisClusterAsyncCommands<byte[], byte[]> connection, T1 t1);
|
||||
}
|
||||
|
||||
/**
|
||||
* A function accepting {@link RedisClusterAsyncCommands} with 2 arguments.
|
||||
*
|
||||
* @param <T1>
|
||||
* @param <T2>
|
||||
* @param <R>
|
||||
*/
|
||||
@FunctionalInterface
|
||||
public interface ConnectionFunction2<T1, T2, R> {
|
||||
|
||||
/**
|
||||
* Apply this function to the arguments and return a {@link RedisFuture}.
|
||||
*/
|
||||
RedisFuture<R> apply(RedisClusterAsyncCommands<byte[], byte[]> connection, T1 t1, T2 t2);
|
||||
}
|
||||
|
||||
/**
|
||||
* A function accepting {@link RedisClusterAsyncCommands} with 3 arguments.
|
||||
*
|
||||
* @param <T1>
|
||||
* @param <T2>
|
||||
* @param <T3>
|
||||
* @param <R>
|
||||
*/
|
||||
@FunctionalInterface
|
||||
public interface ConnectionFunction3<T1, T2, T3, R> {
|
||||
|
||||
/**
|
||||
* Apply this function to the arguments and return a {@link RedisFuture}.
|
||||
*/
|
||||
RedisFuture<R> apply(RedisClusterAsyncCommands<byte[], byte[]> connection, T1 t1, T2 t2, T3 t3);
|
||||
}
|
||||
|
||||
/**
|
||||
* A function accepting {@link RedisClusterAsyncCommands} with 4 arguments.
|
||||
*
|
||||
* @param <T1>
|
||||
* @param <T2>
|
||||
* @param <T3>
|
||||
* @param <T4>
|
||||
* @param <R>
|
||||
*/
|
||||
@FunctionalInterface
|
||||
public interface ConnectionFunction4<T1, T2, T3, T4, R> {
|
||||
|
||||
/**
|
||||
* Apply this function to the arguments and return a {@link RedisFuture}.
|
||||
*/
|
||||
RedisFuture<R> apply(RedisClusterAsyncCommands<byte[], byte[]> connection, T1 t1, T2 t2, T3 t3, T4 t4);
|
||||
}
|
||||
|
||||
/**
|
||||
* A function accepting {@link RedisClusterAsyncCommands} with 5 arguments.
|
||||
*
|
||||
* @param <T1>
|
||||
* @param <T2>
|
||||
* @param <T3>
|
||||
* @param <T4>
|
||||
* @param <T5>
|
||||
* @param <R>
|
||||
*/
|
||||
@FunctionalInterface
|
||||
public interface ConnectionFunction5<T1, T2, T3, T4, T5, R> {
|
||||
|
||||
/**
|
||||
* Apply this function to the arguments and return a {@link RedisFuture}.
|
||||
*/
|
||||
RedisFuture<R> apply(RedisClusterAsyncCommands<byte[], byte[]> connection, T1 t1, T2 t2, T3 t3, T4 t4, T5 t5);
|
||||
}
|
||||
|
||||
/**
|
||||
* A function accepting {@link RedisClusterAsyncCommands} with 6 arguments.
|
||||
*
|
||||
* @param <T1>
|
||||
* @param <T2>
|
||||
* @param <T3>
|
||||
* @param <T4>
|
||||
* @param <T5>
|
||||
* @param <T6>
|
||||
* @param <R>
|
||||
*/
|
||||
@FunctionalInterface
|
||||
public interface ConnectionFunction6<T1, T2, T3, T4, T5, T6, R> {
|
||||
|
||||
/**
|
||||
* Apply this function to the arguments and return a {@link RedisFuture}.
|
||||
*/
|
||||
RedisFuture<R> apply(RedisClusterAsyncCommands<byte[], byte[]> connection, T1 t1, T2 t2, T3 t3, T4 t4, T5 t5,
|
||||
T6 t6);
|
||||
}
|
||||
|
||||
/**
|
||||
* A function accepting {@link RedisClusterAsyncCommands} with 7 arguments.
|
||||
*
|
||||
* @param <T1>
|
||||
* @param <T2>
|
||||
* @param <T3>
|
||||
* @param <T4>
|
||||
* @param <T5>
|
||||
* @param <T6>
|
||||
* @param <T7>
|
||||
* @param <R>
|
||||
*/
|
||||
@FunctionalInterface
|
||||
public interface ConnectionFunction7<T1, T2, T3, T4, T5, T6, T7, R> {
|
||||
|
||||
/**
|
||||
* Apply this function to the arguments and return a {@link RedisFuture}.
|
||||
*/
|
||||
RedisFuture<R> apply(RedisClusterAsyncCommands<byte[], byte[]> connection, T1 t1, T2 t2, T3 t3, T4 t4, T5 t5, T6 t6,
|
||||
T7 t7);
|
||||
}
|
||||
|
||||
/**
|
||||
* A function accepting {@link RedisClusterAsyncCommands} with 8 arguments.
|
||||
*
|
||||
* @param <T1>
|
||||
* @param <T2>
|
||||
* @param <T3>
|
||||
* @param <T4>
|
||||
* @param <T5>
|
||||
* @param <T6>
|
||||
* @param <T7>
|
||||
* @param <T8>
|
||||
* @param <R>
|
||||
*/
|
||||
@FunctionalInterface
|
||||
public interface ConnectionFunction8<T1, T2, T3, T4, T5, T6, T7, T8, R> {
|
||||
|
||||
/**
|
||||
* Apply this function to the arguments and return a {@link RedisFuture}.
|
||||
*/
|
||||
RedisFuture<R> apply(RedisClusterAsyncCommands<byte[], byte[]> connection, T1 t1, T2 t2, T3 t3, T4 t4, T5 t5, T6 t6,
|
||||
T7 t7, T8 t8);
|
||||
}
|
||||
|
||||
static class DefaultSingleInvocationSpec<S> implements SingleInvocationSpec<S> {
|
||||
|
||||
private final Supplier<RedisFuture<S>> parent;
|
||||
private final Synchronizer synchronizer;
|
||||
|
||||
public DefaultSingleInvocationSpec(Supplier<RedisFuture<S>> parent, Synchronizer synchronizer) {
|
||||
this.parent = parent;
|
||||
this.synchronizer = synchronizer;
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> T get(Converter<S, T> converter) {
|
||||
|
||||
Assert.notNull(converter, "Converter must not be null");
|
||||
|
||||
return synchronizer.invoke(parent, converter, () -> null);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public <T> T getOrElse(Converter<S, T> converter, Supplier<T> nullDefault) {
|
||||
|
||||
Assert.notNull(converter, "Converter must not be null");
|
||||
|
||||
return synchronizer.invoke(parent, converter, nullDefault);
|
||||
}
|
||||
}
|
||||
|
||||
static class DefaultManyInvocationSpec<S> implements ManyInvocationSpec<S> {
|
||||
|
||||
private final Supplier<RedisFuture<Collection<S>>> parent;
|
||||
private final Synchronizer synchronizer;
|
||||
|
||||
public DefaultManyInvocationSpec(Supplier<RedisFuture<? extends Collection<S>>> parent, Synchronizer synchronizer) {
|
||||
this.parent = (Supplier) parent;
|
||||
this.synchronizer = synchronizer;
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> List<T> toList(Converter<S, T> converter) {
|
||||
|
||||
Assert.notNull(converter, "Converter must not be null");
|
||||
|
||||
return synchronizer.invoke(parent, source -> {
|
||||
|
||||
if (source.isEmpty()) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
List<T> result = new ArrayList<>(source.size());
|
||||
|
||||
for (S s : source) {
|
||||
result.add(converter.convert(s));
|
||||
}
|
||||
|
||||
return result;
|
||||
}, Collections::emptyList);
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> Set<T> toSet(Converter<S, T> converter) {
|
||||
|
||||
Assert.notNull(converter, "Converter must not be null");
|
||||
|
||||
return synchronizer.invoke(parent, source -> {
|
||||
|
||||
if (source.isEmpty()) {
|
||||
return Collections.emptySet();
|
||||
}
|
||||
|
||||
Set<T> result = new LinkedHashSet<>(source.size());
|
||||
|
||||
for (S s : source) {
|
||||
result.add(converter.convert(s));
|
||||
}
|
||||
|
||||
return result;
|
||||
}, Collections::emptySet);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Interface to define a synchronization function to evaluate {@link RedisFuture}.
|
||||
*/
|
||||
interface Synchronizer {
|
||||
|
||||
@Nullable
|
||||
@SuppressWarnings({ "unchecked", "rawtypes" })
|
||||
default <I, T> T invoke(Supplier<RedisFuture<I>> futureSupplier) {
|
||||
return (T) doInvoke((Supplier) futureSupplier, identityConverter(), () -> null);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@SuppressWarnings({ "unchecked", "rawtypes" })
|
||||
default <I, T> T invoke(Supplier<RedisFuture<I>> futureSupplier, Converter<I, T> converter,
|
||||
Supplier<T> nullDefault) {
|
||||
return (T) doInvoke((Supplier) futureSupplier, (Converter<Object, Object>) converter,
|
||||
(Supplier<Object>) nullDefault);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
Object doInvoke(Supplier<RedisFuture<Object>> futureSupplier, Converter<Object, Object> converter,
|
||||
Supplier<Object> nullDefault);
|
||||
|
||||
}
|
||||
}
|
||||
@@ -20,15 +20,13 @@ import io.lettuce.core.RestoreArgs;
|
||||
import io.lettuce.core.ScanArgs;
|
||||
import io.lettuce.core.ScanCursor;
|
||||
import io.lettuce.core.SortArgs;
|
||||
import io.lettuce.core.cluster.api.async.RedisClusterAsyncCommands;
|
||||
import io.lettuce.core.cluster.api.sync.RedisClusterCommands;
|
||||
import io.lettuce.core.api.async.RedisKeyAsyncCommands;
|
||||
|
||||
import java.time.Duration;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import org.springframework.dao.DataAccessException;
|
||||
import org.springframework.data.redis.connection.DataType;
|
||||
import org.springframework.data.redis.connection.RedisKeyCommands;
|
||||
import org.springframework.data.redis.connection.SortParameters;
|
||||
@@ -62,21 +60,7 @@ class LettuceKeyCommands implements RedisKeyCommands {
|
||||
|
||||
Assert.notNull(key, "Key must not be null!");
|
||||
|
||||
try {
|
||||
if (isPipelined()) {
|
||||
pipeline(connection.newLettuceResult(getAsyncConnection().exists(new byte[][] { key }),
|
||||
LettuceConverters.longToBooleanConverter()));
|
||||
return null;
|
||||
}
|
||||
if (isQueueing()) {
|
||||
transaction(connection.newLettuceResult(getAsyncConnection().exists(new byte[][] { key }),
|
||||
LettuceConverters.longToBooleanConverter()));
|
||||
return null;
|
||||
}
|
||||
return LettuceConverters.longToBooleanConverter().convert(getConnection().exists(new byte[][] { key }));
|
||||
} catch (Exception ex) {
|
||||
throw convertLettuceAccessException(ex);
|
||||
}
|
||||
return connection.invoke().from(RedisKeyAsyncCommands::exists, key).get(LettuceConverters.longToBooleanConverter());
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -90,19 +74,7 @@ class LettuceKeyCommands implements RedisKeyCommands {
|
||||
Assert.notNull(keys, "Keys must not be null!");
|
||||
Assert.noNullElements(keys, "Keys must not contain null elements!");
|
||||
|
||||
try {
|
||||
if (isPipelined()) {
|
||||
pipeline(connection.newLettuceResult(getAsyncConnection().exists(keys)));
|
||||
return null;
|
||||
}
|
||||
if (isQueueing()) {
|
||||
transaction(connection.newLettuceResult(getAsyncConnection().exists(keys)));
|
||||
return null;
|
||||
}
|
||||
return getConnection().exists(keys);
|
||||
} catch (Exception ex) {
|
||||
throw convertLettuceAccessException(ex);
|
||||
}
|
||||
return connection.invoke().just(RedisKeyAsyncCommands::exists, keys);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -115,19 +87,7 @@ class LettuceKeyCommands implements RedisKeyCommands {
|
||||
Assert.notNull(keys, "Keys must not be null!");
|
||||
Assert.noNullElements(keys, "Keys must not contain null elements!");
|
||||
|
||||
try {
|
||||
if (isPipelined()) {
|
||||
pipeline(connection.newLettuceResult(getAsyncConnection().del(keys)));
|
||||
return null;
|
||||
}
|
||||
if (isQueueing()) {
|
||||
transaction(connection.newLettuceResult(getAsyncConnection().del(keys)));
|
||||
return null;
|
||||
}
|
||||
return getConnection().del(keys);
|
||||
} catch (Exception ex) {
|
||||
throw convertLettuceAccessException(ex);
|
||||
}
|
||||
return connection.invoke().just(RedisKeyAsyncCommands::del, keys);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -139,19 +99,7 @@ class LettuceKeyCommands implements RedisKeyCommands {
|
||||
|
||||
Assert.notNull(keys, "Keys must not be null!");
|
||||
|
||||
try {
|
||||
if (isPipelined()) {
|
||||
pipeline(connection.newLettuceResult(getAsyncConnection().unlink(keys)));
|
||||
return null;
|
||||
}
|
||||
if (isQueueing()) {
|
||||
transaction(connection.newLettuceResult(getAsyncConnection().unlink(keys)));
|
||||
return null;
|
||||
}
|
||||
return getConnection().unlink(keys);
|
||||
} catch (Exception ex) {
|
||||
throw convertLettuceAccessException(ex);
|
||||
}
|
||||
return connection.invoke().just(RedisKeyAsyncCommands::unlink, keys);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -163,19 +111,7 @@ class LettuceKeyCommands implements RedisKeyCommands {
|
||||
|
||||
Assert.notNull(key, "Key must not be null!");
|
||||
|
||||
try {
|
||||
if (isPipelined()) {
|
||||
pipeline(connection.newLettuceResult(getAsyncConnection().type(key), LettuceConverters.stringToDataType()));
|
||||
return null;
|
||||
}
|
||||
if (isQueueing()) {
|
||||
transaction(connection.newLettuceResult(getAsyncConnection().type(key), LettuceConverters.stringToDataType()));
|
||||
return null;
|
||||
}
|
||||
return LettuceConverters.toDataType(getConnection().type(key));
|
||||
} catch (Exception ex) {
|
||||
throw convertLettuceAccessException(ex);
|
||||
}
|
||||
return connection.invoke().from(RedisKeyAsyncCommands::type, key).get(LettuceConverters.stringToDataType());
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -187,19 +123,7 @@ class LettuceKeyCommands implements RedisKeyCommands {
|
||||
|
||||
Assert.notNull(keys, "Keys must not be null!");
|
||||
|
||||
try {
|
||||
if (isPipelined()) {
|
||||
pipeline(connection.newLettuceResult(getAsyncConnection().touch(keys)));
|
||||
return null;
|
||||
}
|
||||
if (isQueueing()) {
|
||||
transaction(connection.newLettuceResult(getAsyncConnection().touch(keys)));
|
||||
return null;
|
||||
}
|
||||
return getConnection().touch(keys);
|
||||
} catch (Exception ex) {
|
||||
throw convertLettuceAccessException(ex);
|
||||
}
|
||||
return connection.invoke().just(RedisKeyAsyncCommands::touch, keys);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -211,21 +135,7 @@ class LettuceKeyCommands implements RedisKeyCommands {
|
||||
|
||||
Assert.notNull(pattern, "Pattern must not be null!");
|
||||
|
||||
try {
|
||||
if (isPipelined()) {
|
||||
pipeline(
|
||||
connection.newLettuceResult(getAsyncConnection().keys(pattern), LettuceConverters.bytesListToBytesSet()));
|
||||
return null;
|
||||
}
|
||||
if (isQueueing()) {
|
||||
transaction(
|
||||
connection.newLettuceResult(getAsyncConnection().keys(pattern), LettuceConverters.bytesListToBytesSet()));
|
||||
return null;
|
||||
}
|
||||
return LettuceConverters.toBytesSet(getConnection().keys(pattern));
|
||||
} catch (Exception ex) {
|
||||
throw convertLettuceAccessException(ex);
|
||||
}
|
||||
return connection.invoke().from(RedisKeyAsyncCommands::keys, pattern).get(LettuceConverters.bytesListToBytesSet());
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -257,13 +167,12 @@ class LettuceKeyCommands implements RedisKeyCommands {
|
||||
@Override
|
||||
protected LettuceScanIteration<byte[]> doScan(ScanCursor cursor, ScanOptions options) {
|
||||
|
||||
if (isQueueing() || isPipelined()) {
|
||||
if (connection.isQueueing() || connection.isPipelined()) {
|
||||
throw new UnsupportedOperationException("'SCAN' cannot be called in pipeline / transaction mode.");
|
||||
}
|
||||
|
||||
ScanArgs scanArgs = LettuceConverters.toScanArgs(options);
|
||||
|
||||
KeyScanCursor<byte[]> keyScanCursor = getConnection().scan(cursor, scanArgs);
|
||||
KeyScanCursor<byte[]> keyScanCursor = connection.invoke().just(RedisKeyAsyncCommands::scan, cursor, scanArgs);
|
||||
List<byte[]> keys = keyScanCursor.getKeys();
|
||||
|
||||
return new LettuceScanIteration<>(keyScanCursor, keys);
|
||||
@@ -283,20 +192,7 @@ class LettuceKeyCommands implements RedisKeyCommands {
|
||||
*/
|
||||
@Override
|
||||
public byte[] randomKey() {
|
||||
|
||||
try {
|
||||
if (isPipelined()) {
|
||||
pipeline(connection.newLettuceResult(getAsyncConnection().randomkey()));
|
||||
return null;
|
||||
}
|
||||
if (isQueueing()) {
|
||||
transaction(connection.newLettuceResult(getAsyncConnection().randomkey()));
|
||||
return null;
|
||||
}
|
||||
return getConnection().randomkey();
|
||||
} catch (Exception ex) {
|
||||
throw convertLettuceAccessException(ex);
|
||||
}
|
||||
return connection.invoke().just(RedisKeyAsyncCommands::randomkey);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -309,19 +205,7 @@ class LettuceKeyCommands implements RedisKeyCommands {
|
||||
Assert.notNull(sourceKey, "Source key must not be null!");
|
||||
Assert.notNull(targetKey, "Target key must not be null!");
|
||||
|
||||
try {
|
||||
if (isPipelined()) {
|
||||
pipeline(connection.newLettuceStatusResult(getAsyncConnection().rename(sourceKey, targetKey)));
|
||||
return;
|
||||
}
|
||||
if (isQueueing()) {
|
||||
transaction(connection.newLettuceStatusResult(getAsyncConnection().rename(sourceKey, targetKey)));
|
||||
return;
|
||||
}
|
||||
getConnection().rename(sourceKey, targetKey);
|
||||
} catch (Exception ex) {
|
||||
throw convertLettuceAccessException(ex);
|
||||
}
|
||||
connection.invokeStatus().just(RedisKeyAsyncCommands::rename, sourceKey, targetKey);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -334,19 +218,7 @@ class LettuceKeyCommands implements RedisKeyCommands {
|
||||
Assert.notNull(sourceKey, "Source key must not be null!");
|
||||
Assert.notNull(targetKey, "Target key must not be null!");
|
||||
|
||||
try {
|
||||
if (isPipelined()) {
|
||||
pipeline(connection.newLettuceResult(getAsyncConnection().renamenx(sourceKey, targetKey)));
|
||||
return null;
|
||||
}
|
||||
if (isQueueing()) {
|
||||
transaction(connection.newLettuceResult(getAsyncConnection().renamenx(sourceKey, targetKey)));
|
||||
return null;
|
||||
}
|
||||
return (getConnection().renamenx(sourceKey, targetKey));
|
||||
} catch (Exception ex) {
|
||||
throw convertLettuceAccessException(ex);
|
||||
}
|
||||
return connection.invoke().just(RedisKeyAsyncCommands::renamenx, sourceKey, targetKey);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -358,19 +230,7 @@ class LettuceKeyCommands implements RedisKeyCommands {
|
||||
|
||||
Assert.notNull(key, "Key must not be null!");
|
||||
|
||||
try {
|
||||
if (isPipelined()) {
|
||||
pipeline(connection.newLettuceResult(getAsyncConnection().expire(key, seconds)));
|
||||
return null;
|
||||
}
|
||||
if (isQueueing()) {
|
||||
transaction(connection.newLettuceResult(getAsyncConnection().expire(key, seconds)));
|
||||
return null;
|
||||
}
|
||||
return getConnection().expire(key, seconds);
|
||||
} catch (Exception ex) {
|
||||
throw convertLettuceAccessException(ex);
|
||||
}
|
||||
return connection.invoke().just(RedisKeyAsyncCommands::expire, key, seconds);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -382,19 +242,7 @@ class LettuceKeyCommands implements RedisKeyCommands {
|
||||
|
||||
Assert.notNull(key, "Key must not be null!");
|
||||
|
||||
try {
|
||||
if (isPipelined()) {
|
||||
pipeline(connection.newLettuceResult(getAsyncConnection().pexpire(key, millis)));
|
||||
return null;
|
||||
}
|
||||
if (isQueueing()) {
|
||||
transaction(connection.newLettuceResult(getAsyncConnection().pexpire(key, millis)));
|
||||
return null;
|
||||
}
|
||||
return getConnection().pexpire(key, millis);
|
||||
} catch (Exception ex) {
|
||||
throw convertLettuceAccessException(ex);
|
||||
}
|
||||
return connection.invoke().just(RedisKeyAsyncCommands::pexpire, key, millis);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -406,19 +254,7 @@ class LettuceKeyCommands implements RedisKeyCommands {
|
||||
|
||||
Assert.notNull(key, "Key must not be null!");
|
||||
|
||||
try {
|
||||
if (isPipelined()) {
|
||||
pipeline(connection.newLettuceResult(getAsyncConnection().expireat(key, unixTime)));
|
||||
return null;
|
||||
}
|
||||
if (isQueueing()) {
|
||||
transaction(connection.newLettuceResult(getAsyncConnection().expireat(key, unixTime)));
|
||||
return null;
|
||||
}
|
||||
return getConnection().expireat(key, unixTime);
|
||||
} catch (Exception ex) {
|
||||
throw convertLettuceAccessException(ex);
|
||||
}
|
||||
return connection.invoke().just(RedisKeyAsyncCommands::expireat, key, unixTime);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -430,19 +266,7 @@ class LettuceKeyCommands implements RedisKeyCommands {
|
||||
|
||||
Assert.notNull(key, "Key must not be null!");
|
||||
|
||||
try {
|
||||
if (isPipelined()) {
|
||||
pipeline(connection.newLettuceResult(getAsyncConnection().pexpireat(key, unixTimeInMillis)));
|
||||
return null;
|
||||
}
|
||||
if (isQueueing()) {
|
||||
transaction(connection.newLettuceResult(getAsyncConnection().pexpireat(key, unixTimeInMillis)));
|
||||
return null;
|
||||
}
|
||||
return getConnection().pexpireat(key, unixTimeInMillis);
|
||||
} catch (Exception ex) {
|
||||
throw convertLettuceAccessException(ex);
|
||||
}
|
||||
return connection.invoke().just(RedisKeyAsyncCommands::pexpireat, key, unixTimeInMillis);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -454,19 +278,7 @@ class LettuceKeyCommands implements RedisKeyCommands {
|
||||
|
||||
Assert.notNull(key, "Key must not be null!");
|
||||
|
||||
try {
|
||||
if (isPipelined()) {
|
||||
pipeline(connection.newLettuceResult(getAsyncConnection().persist(key)));
|
||||
return null;
|
||||
}
|
||||
if (isQueueing()) {
|
||||
transaction(connection.newLettuceResult(getAsyncConnection().persist(key)));
|
||||
return null;
|
||||
}
|
||||
return getConnection().persist(key);
|
||||
} catch (Exception ex) {
|
||||
throw convertLettuceAccessException(ex);
|
||||
}
|
||||
return connection.invoke().just(RedisKeyAsyncCommands::persist, key);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -478,19 +290,7 @@ class LettuceKeyCommands implements RedisKeyCommands {
|
||||
|
||||
Assert.notNull(key, "Key must not be null!");
|
||||
|
||||
try {
|
||||
if (isPipelined()) {
|
||||
pipeline(connection.newLettuceResult(getAsyncConnection().move(key, dbIndex)));
|
||||
return null;
|
||||
}
|
||||
if (isQueueing()) {
|
||||
transaction(connection.newLettuceResult(getAsyncConnection().move(key, dbIndex)));
|
||||
return null;
|
||||
}
|
||||
return getConnection().move(key, dbIndex);
|
||||
} catch (Exception ex) {
|
||||
throw convertLettuceAccessException(ex);
|
||||
}
|
||||
return connection.invoke().just(RedisKeyAsyncCommands::move, key, dbIndex);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -502,20 +302,7 @@ class LettuceKeyCommands implements RedisKeyCommands {
|
||||
|
||||
Assert.notNull(key, "Key must not be null!");
|
||||
|
||||
try {
|
||||
if (isPipelined()) {
|
||||
pipeline(connection.newLettuceResult(getAsyncConnection().ttl(key)));
|
||||
return null;
|
||||
}
|
||||
if (isQueueing()) {
|
||||
transaction(connection.newLettuceResult(getAsyncConnection().ttl(key)));
|
||||
return null;
|
||||
}
|
||||
|
||||
return getConnection().ttl(key);
|
||||
} catch (Exception ex) {
|
||||
throw convertLettuceAccessException(ex);
|
||||
}
|
||||
return connection.invoke().just(RedisKeyAsyncCommands::ttl, key);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -527,20 +314,7 @@ class LettuceKeyCommands implements RedisKeyCommands {
|
||||
|
||||
Assert.notNull(key, "Key must not be null!");
|
||||
|
||||
try {
|
||||
if (isPipelined()) {
|
||||
pipeline(connection.newLettuceResult(getAsyncConnection().ttl(key), Converters.secondsToTimeUnit(timeUnit)));
|
||||
return null;
|
||||
}
|
||||
if (isQueueing()) {
|
||||
transaction(connection.newLettuceResult(getAsyncConnection().ttl(key), Converters.secondsToTimeUnit(timeUnit)));
|
||||
return null;
|
||||
}
|
||||
|
||||
return Converters.secondsToTimeUnit(getConnection().ttl(key), timeUnit);
|
||||
} catch (Exception ex) {
|
||||
throw convertLettuceAccessException(ex);
|
||||
}
|
||||
return connection.invoke().from(RedisKeyAsyncCommands::ttl, key).get(Converters.secondsToTimeUnit(timeUnit));
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -552,20 +326,7 @@ class LettuceKeyCommands implements RedisKeyCommands {
|
||||
|
||||
Assert.notNull(key, "Key must not be null!");
|
||||
|
||||
try {
|
||||
if (isPipelined()) {
|
||||
pipeline(connection.newLettuceResult(getAsyncConnection().pttl(key)));
|
||||
return null;
|
||||
}
|
||||
if (isQueueing()) {
|
||||
transaction(connection.newLettuceResult(getAsyncConnection().pttl(key)));
|
||||
return null;
|
||||
}
|
||||
|
||||
return getConnection().pttl(key);
|
||||
} catch (Exception ex) {
|
||||
throw convertLettuceAccessException(ex);
|
||||
}
|
||||
return connection.invoke().just(RedisKeyAsyncCommands::pttl, key);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -577,22 +338,7 @@ class LettuceKeyCommands implements RedisKeyCommands {
|
||||
|
||||
Assert.notNull(key, "Key must not be null!");
|
||||
|
||||
try {
|
||||
if (isPipelined()) {
|
||||
pipeline(
|
||||
connection.newLettuceResult(getAsyncConnection().pttl(key), Converters.millisecondsToTimeUnit(timeUnit)));
|
||||
return null;
|
||||
}
|
||||
if (isQueueing()) {
|
||||
transaction(
|
||||
connection.newLettuceResult(getAsyncConnection().pttl(key), Converters.millisecondsToTimeUnit(timeUnit)));
|
||||
return null;
|
||||
}
|
||||
|
||||
return Converters.millisecondsToTimeUnit(getConnection().pttl(key), timeUnit);
|
||||
} catch (Exception ex) {
|
||||
throw convertLettuceAccessException(ex);
|
||||
}
|
||||
return connection.invoke().from(RedisKeyAsyncCommands::pttl, key).get(Converters.millisecondsToTimeUnit(timeUnit));
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -606,19 +352,7 @@ class LettuceKeyCommands implements RedisKeyCommands {
|
||||
|
||||
SortArgs args = LettuceConverters.toSortArgs(params);
|
||||
|
||||
try {
|
||||
if (isPipelined()) {
|
||||
pipeline(connection.newLettuceResult(getAsyncConnection().sort(key, args)));
|
||||
return null;
|
||||
}
|
||||
if (isQueueing()) {
|
||||
transaction(connection.newLettuceResult(getAsyncConnection().sort(key, args)));
|
||||
return null;
|
||||
}
|
||||
return getConnection().sort(key, args);
|
||||
} catch (Exception ex) {
|
||||
throw convertLettuceAccessException(ex);
|
||||
}
|
||||
return connection.invoke().just(RedisKeyAsyncCommands::sort, key, args);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -632,19 +366,7 @@ class LettuceKeyCommands implements RedisKeyCommands {
|
||||
|
||||
SortArgs args = LettuceConverters.toSortArgs(params);
|
||||
|
||||
try {
|
||||
if (isPipelined()) {
|
||||
pipeline(connection.newLettuceResult(getAsyncConnection().sortStore(key, args, sortKey)));
|
||||
return null;
|
||||
}
|
||||
if (isQueueing()) {
|
||||
transaction(connection.newLettuceResult(getAsyncConnection().sortStore(key, args, sortKey)));
|
||||
return null;
|
||||
}
|
||||
return getConnection().sortStore(key, args, sortKey);
|
||||
} catch (Exception ex) {
|
||||
throw convertLettuceAccessException(ex);
|
||||
}
|
||||
return connection.invoke().just(RedisKeyAsyncCommands::sortStore, key, args, sortKey);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -656,19 +378,7 @@ class LettuceKeyCommands implements RedisKeyCommands {
|
||||
|
||||
Assert.notNull(key, "Key must not be null!");
|
||||
|
||||
try {
|
||||
if (isPipelined()) {
|
||||
pipeline(connection.newLettuceResult(getAsyncConnection().dump(key)));
|
||||
return null;
|
||||
}
|
||||
if (isQueueing()) {
|
||||
transaction(connection.newLettuceResult(getAsyncConnection().dump(key)));
|
||||
return null;
|
||||
}
|
||||
return getConnection().dump(key);
|
||||
} catch (Exception ex) {
|
||||
throw convertLettuceAccessException(ex);
|
||||
}
|
||||
return connection.invoke().just(RedisKeyAsyncCommands::dump, key);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -681,24 +391,9 @@ class LettuceKeyCommands implements RedisKeyCommands {
|
||||
Assert.notNull(key, "Key must not be null!");
|
||||
Assert.notNull(serializedValue, "Serialized value must not be null!");
|
||||
|
||||
try {
|
||||
RestoreArgs restoreArgs = RestoreArgs.Builder.ttl(ttlInMillis).replace(replace);
|
||||
|
||||
RestoreArgs restoreArgs = RestoreArgs.Builder.ttl(ttlInMillis).replace(replace);
|
||||
|
||||
if (isPipelined()) {
|
||||
pipeline(connection.newLettuceStatusResult(getAsyncConnection().restore(key, serializedValue, restoreArgs)));
|
||||
return;
|
||||
}
|
||||
|
||||
if (isQueueing()) {
|
||||
transaction(connection.newLettuceStatusResult(getAsyncConnection().restore(key, serializedValue, restoreArgs)));
|
||||
return;
|
||||
}
|
||||
|
||||
getConnection().restore(key, serializedValue, restoreArgs);
|
||||
} catch (Exception ex) {
|
||||
throw convertLettuceAccessException(ex);
|
||||
}
|
||||
connection.invokeStatus().just(RedisKeyAsyncCommands::restore, key, serializedValue, restoreArgs);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -711,22 +406,8 @@ class LettuceKeyCommands implements RedisKeyCommands {
|
||||
|
||||
Assert.notNull(key, "Key must not be null!");
|
||||
|
||||
try {
|
||||
if (isPipelined()) {
|
||||
pipeline(connection.newLettuceResult(getAsyncConnection().objectEncoding(key), ValueEncoding::of,
|
||||
() -> RedisValueEncoding.VACANT));
|
||||
return null;
|
||||
}
|
||||
if (isQueueing()) {
|
||||
transaction(connection.newLettuceResult(getAsyncConnection().objectEncoding(key), ValueEncoding::of,
|
||||
() -> RedisValueEncoding.VACANT));
|
||||
return null;
|
||||
}
|
||||
|
||||
return ValueEncoding.of(getConnection().objectEncoding(key));
|
||||
} catch (Exception ex) {
|
||||
throw convertLettuceAccessException(ex);
|
||||
}
|
||||
return connection.invokeStatus().from(RedisKeyAsyncCommands::objectEncoding, key).getOrElse(ValueEncoding::of,
|
||||
() -> RedisValueEncoding.VACANT);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -739,21 +420,7 @@ class LettuceKeyCommands implements RedisKeyCommands {
|
||||
|
||||
Assert.notNull(key, "Key must not be null!");
|
||||
|
||||
try {
|
||||
if (isPipelined()) {
|
||||
pipeline(connection.newLettuceResult(getAsyncConnection().objectIdletime(key), Converters::secondsToDuration));
|
||||
return null;
|
||||
}
|
||||
if (isQueueing()) {
|
||||
transaction(
|
||||
connection.newLettuceResult(getAsyncConnection().objectIdletime(key), Converters::secondsToDuration));
|
||||
return null;
|
||||
}
|
||||
|
||||
return Converters.secondsToDuration(getConnection().objectIdletime(key));
|
||||
} catch (Exception ex) {
|
||||
throw convertLettuceAccessException(ex);
|
||||
}
|
||||
return connection.invoke().from(RedisKeyAsyncCommands::objectIdletime, key).get(Converters::secondsToDuration);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -766,48 +433,6 @@ class LettuceKeyCommands implements RedisKeyCommands {
|
||||
|
||||
Assert.notNull(key, "Key must not be null!");
|
||||
|
||||
try {
|
||||
if (isPipelined()) {
|
||||
pipeline(connection.newLettuceResult(getAsyncConnection().objectRefcount(key)));
|
||||
return null;
|
||||
}
|
||||
if (isQueueing()) {
|
||||
transaction(connection.newLettuceResult(getAsyncConnection().objectRefcount(key)));
|
||||
return null;
|
||||
}
|
||||
|
||||
return getConnection().objectRefcount(key);
|
||||
} catch (Exception ex) {
|
||||
throw convertLettuceAccessException(ex);
|
||||
}
|
||||
return connection.invoke().just(RedisKeyAsyncCommands::objectRefcount, key);
|
||||
}
|
||||
|
||||
private boolean isPipelined() {
|
||||
return connection.isPipelined();
|
||||
}
|
||||
|
||||
private boolean isQueueing() {
|
||||
return connection.isQueueing();
|
||||
}
|
||||
|
||||
private void pipeline(LettuceResult result) {
|
||||
connection.pipeline(result);
|
||||
}
|
||||
|
||||
private void transaction(LettuceResult result) {
|
||||
connection.transaction(result);
|
||||
}
|
||||
|
||||
private RedisClusterAsyncCommands<byte[], byte[]> getAsyncConnection() {
|
||||
return connection.getAsyncConnection();
|
||||
}
|
||||
|
||||
public RedisClusterCommands<byte[], byte[]> getConnection() {
|
||||
return connection.getConnection();
|
||||
}
|
||||
|
||||
private DataAccessException convertLettuceAccessException(Exception ex) {
|
||||
return connection.convertLettuceAccessException(ex);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -16,13 +16,11 @@
|
||||
package org.springframework.data.redis.connection.lettuce;
|
||||
|
||||
import io.lettuce.core.LPosArgs;
|
||||
import io.lettuce.core.cluster.api.async.RedisClusterAsyncCommands;
|
||||
import io.lettuce.core.cluster.api.sync.RedisClusterCommands;
|
||||
import io.lettuce.core.api.async.RedisListAsyncCommands;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
import org.springframework.dao.DataAccessException;
|
||||
import org.springframework.data.redis.connection.RedisListCommands;
|
||||
import org.springframework.lang.Nullable;
|
||||
import org.springframework.util.Assert;
|
||||
@@ -49,19 +47,7 @@ class LettuceListCommands implements RedisListCommands {
|
||||
|
||||
Assert.notNull(key, "Key must not be null!");
|
||||
|
||||
try {
|
||||
if (isPipelined()) {
|
||||
pipeline(connection.newLettuceResult(getAsyncConnection().rpush(key, values)));
|
||||
return null;
|
||||
}
|
||||
if (isQueueing()) {
|
||||
transaction(connection.newLettuceResult(getAsyncConnection().rpush(key, values)));
|
||||
return null;
|
||||
}
|
||||
return getConnection().rpush(key, values);
|
||||
} catch (Exception ex) {
|
||||
throw convertLettuceAccessException(ex);
|
||||
}
|
||||
return connection.invoke().just(RedisListAsyncCommands::rpush, key, values);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -78,33 +64,12 @@ class LettuceListCommands implements RedisListCommands {
|
||||
if (rank != null) {
|
||||
args.rank(rank);
|
||||
}
|
||||
try {
|
||||
if (isPipelined()) {
|
||||
if (count != null) {
|
||||
pipeline(connection.newLettuceResult(getAsyncConnection().lpos(key, element, count, args)));
|
||||
} else {
|
||||
pipeline(
|
||||
connection.newLettuceResult(getAsyncConnection().lpos(key, element, args), Collections::singletonList));
|
||||
}
|
||||
return null;
|
||||
}
|
||||
if (isQueueing()) {
|
||||
if (count != null) {
|
||||
transaction(connection.newLettuceResult(getAsyncConnection().lpos(key, element, count, args)));
|
||||
} else {
|
||||
transaction(
|
||||
connection.newLettuceResult(getAsyncConnection().lpos(key, element, args), Collections::singletonList));
|
||||
}
|
||||
return null;
|
||||
}
|
||||
if (count != null) {
|
||||
return getConnection().lpos(key, element, count, args);
|
||||
}
|
||||
|
||||
return Collections.singletonList(getConnection().lpos(key, element, args));
|
||||
} catch (Exception ex) {
|
||||
throw convertLettuceAccessException(ex);
|
||||
if (count != null) {
|
||||
return connection.invoke().just(RedisListAsyncCommands::lpos, key, element, count, args);
|
||||
}
|
||||
|
||||
return connection.invoke().from(RedisListAsyncCommands::lpos, key, element, args).get(Collections::singletonList);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -118,19 +83,7 @@ class LettuceListCommands implements RedisListCommands {
|
||||
Assert.notNull(values, "Values must not be null!");
|
||||
Assert.noNullElements(values, "Values must not contain null elements!");
|
||||
|
||||
try {
|
||||
if (isPipelined()) {
|
||||
pipeline(connection.newLettuceResult(getAsyncConnection().lpush(key, values)));
|
||||
return null;
|
||||
}
|
||||
if (isQueueing()) {
|
||||
transaction(connection.newLettuceResult(getAsyncConnection().lpush(key, values)));
|
||||
return null;
|
||||
}
|
||||
return getConnection().lpush(key, values);
|
||||
} catch (Exception ex) {
|
||||
throw convertLettuceAccessException(ex);
|
||||
}
|
||||
return connection.invoke().just(RedisListAsyncCommands::lpush, key, values);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -143,19 +96,7 @@ class LettuceListCommands implements RedisListCommands {
|
||||
Assert.notNull(key, "Key must not be null!");
|
||||
Assert.notNull(value, "Value must not be null!");
|
||||
|
||||
try {
|
||||
if (isPipelined()) {
|
||||
pipeline(connection.newLettuceResult(getAsyncConnection().rpushx(key, value)));
|
||||
return null;
|
||||
}
|
||||
if (isQueueing()) {
|
||||
transaction(connection.newLettuceResult(getAsyncConnection().rpushx(key, value)));
|
||||
return null;
|
||||
}
|
||||
return getConnection().rpushx(key, value);
|
||||
} catch (Exception ex) {
|
||||
throw convertLettuceAccessException(ex);
|
||||
}
|
||||
return connection.invoke().just(RedisListAsyncCommands::rpushx, key, value);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -168,19 +109,7 @@ class LettuceListCommands implements RedisListCommands {
|
||||
Assert.notNull(key, "Key must not be null!");
|
||||
Assert.notNull(value, "Value must not be null!");
|
||||
|
||||
try {
|
||||
if (isPipelined()) {
|
||||
pipeline(connection.newLettuceResult(getAsyncConnection().lpushx(key, value)));
|
||||
return null;
|
||||
}
|
||||
if (isQueueing()) {
|
||||
transaction(connection.newLettuceResult(getAsyncConnection().lpushx(key, value)));
|
||||
return null;
|
||||
}
|
||||
return getConnection().lpushx(key, value);
|
||||
} catch (Exception ex) {
|
||||
throw convertLettuceAccessException(ex);
|
||||
}
|
||||
return connection.invoke().just(RedisListAsyncCommands::lpushx, key, value);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -192,19 +121,7 @@ class LettuceListCommands implements RedisListCommands {
|
||||
|
||||
Assert.notNull(key, "Key must not be null!");
|
||||
|
||||
try {
|
||||
if (isPipelined()) {
|
||||
pipeline(connection.newLettuceResult(getAsyncConnection().llen(key)));
|
||||
return null;
|
||||
}
|
||||
if (isQueueing()) {
|
||||
transaction(connection.newLettuceResult(getAsyncConnection().llen(key)));
|
||||
return null;
|
||||
}
|
||||
return getConnection().llen(key);
|
||||
} catch (Exception ex) {
|
||||
throw convertLettuceAccessException(ex);
|
||||
}
|
||||
return connection.invoke().just(RedisListAsyncCommands::llen, key);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -216,19 +133,7 @@ class LettuceListCommands implements RedisListCommands {
|
||||
|
||||
Assert.notNull(key, "Key must not be null!");
|
||||
|
||||
try {
|
||||
if (isPipelined()) {
|
||||
pipeline(connection.newLettuceResult(getAsyncConnection().lrange(key, start, end)));
|
||||
return null;
|
||||
}
|
||||
if (isQueueing()) {
|
||||
transaction(connection.newLettuceResult(getAsyncConnection().lrange(key, start, end)));
|
||||
return null;
|
||||
}
|
||||
return getConnection().lrange(key, start, end);
|
||||
} catch (Exception ex) {
|
||||
throw convertLettuceAccessException(ex);
|
||||
}
|
||||
return connection.invoke().just(RedisListAsyncCommands::lrange, key, start, end);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -240,19 +145,7 @@ class LettuceListCommands implements RedisListCommands {
|
||||
|
||||
Assert.notNull(key, "Key must not be null!");
|
||||
|
||||
try {
|
||||
if (isPipelined()) {
|
||||
pipeline(connection.newLettuceStatusResult(getAsyncConnection().ltrim(key, start, end)));
|
||||
return;
|
||||
}
|
||||
if (isQueueing()) {
|
||||
transaction(connection.newLettuceStatusResult(getAsyncConnection().ltrim(key, start, end)));
|
||||
return;
|
||||
}
|
||||
getConnection().ltrim(key, start, end);
|
||||
} catch (Exception ex) {
|
||||
throw convertLettuceAccessException(ex);
|
||||
}
|
||||
connection.invokeStatus().just(RedisListAsyncCommands::ltrim, key, start, end);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -264,19 +157,7 @@ class LettuceListCommands implements RedisListCommands {
|
||||
|
||||
Assert.notNull(key, "Key must not be null!");
|
||||
|
||||
try {
|
||||
if (isPipelined()) {
|
||||
pipeline(connection.newLettuceResult(getAsyncConnection().lindex(key, index)));
|
||||
return null;
|
||||
}
|
||||
if (isQueueing()) {
|
||||
transaction(connection.newLettuceResult(getAsyncConnection().lindex(key, index)));
|
||||
return null;
|
||||
}
|
||||
return getConnection().lindex(key, index);
|
||||
} catch (Exception ex) {
|
||||
throw convertLettuceAccessException(ex);
|
||||
}
|
||||
return connection.invoke().just(RedisListAsyncCommands::lindex, key, index);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -288,21 +169,8 @@ class LettuceListCommands implements RedisListCommands {
|
||||
|
||||
Assert.notNull(key, "Key must not be null!");
|
||||
|
||||
try {
|
||||
if (isPipelined()) {
|
||||
pipeline(connection
|
||||
.newLettuceResult(getAsyncConnection().linsert(key, LettuceConverters.toBoolean(where), pivot, value)));
|
||||
return null;
|
||||
}
|
||||
if (isQueueing()) {
|
||||
transaction(connection
|
||||
.newLettuceResult(getAsyncConnection().linsert(key, LettuceConverters.toBoolean(where), pivot, value)));
|
||||
return null;
|
||||
}
|
||||
return getConnection().linsert(key, LettuceConverters.toBoolean(where), pivot, value);
|
||||
} catch (Exception ex) {
|
||||
throw convertLettuceAccessException(ex);
|
||||
}
|
||||
return connection.invoke().just(RedisListAsyncCommands::linsert, key, LettuceConverters.toBoolean(where), pivot,
|
||||
value);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -315,19 +183,7 @@ class LettuceListCommands implements RedisListCommands {
|
||||
Assert.notNull(key, "Key must not be null!");
|
||||
Assert.notNull(value, "Value must not be null!");
|
||||
|
||||
try {
|
||||
if (isPipelined()) {
|
||||
pipeline(connection.newLettuceStatusResult(getAsyncConnection().lset(key, index, value)));
|
||||
return;
|
||||
}
|
||||
if (isQueueing()) {
|
||||
transaction(connection.newLettuceStatusResult(getAsyncConnection().lset(key, index, value)));
|
||||
return;
|
||||
}
|
||||
getConnection().lset(key, index, value);
|
||||
} catch (Exception ex) {
|
||||
throw convertLettuceAccessException(ex);
|
||||
}
|
||||
connection.invokeStatus().just(RedisListAsyncCommands::lset, key, index, value);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -340,19 +196,7 @@ class LettuceListCommands implements RedisListCommands {
|
||||
Assert.notNull(key, "Key must not be null!");
|
||||
Assert.notNull(value, "Value must not be null!");
|
||||
|
||||
try {
|
||||
if (isPipelined()) {
|
||||
pipeline(connection.newLettuceResult(getAsyncConnection().lrem(key, count, value)));
|
||||
return null;
|
||||
}
|
||||
if (isQueueing()) {
|
||||
transaction(connection.newLettuceResult(getAsyncConnection().lrem(key, count, value)));
|
||||
return null;
|
||||
}
|
||||
return getConnection().lrem(key, count, value);
|
||||
} catch (Exception ex) {
|
||||
throw convertLettuceAccessException(ex);
|
||||
}
|
||||
return connection.invoke().just(RedisListAsyncCommands::lrem, key, count, value);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -364,19 +208,7 @@ class LettuceListCommands implements RedisListCommands {
|
||||
|
||||
Assert.notNull(key, "Key must not be null!");
|
||||
|
||||
try {
|
||||
if (isPipelined()) {
|
||||
pipeline(connection.newLettuceResult(getAsyncConnection().lpop(key)));
|
||||
return null;
|
||||
}
|
||||
if (isQueueing()) {
|
||||
transaction(connection.newLettuceResult(getAsyncConnection().lpop(key)));
|
||||
return null;
|
||||
}
|
||||
return getConnection().lpop(key);
|
||||
} catch (Exception ex) {
|
||||
throw convertLettuceAccessException(ex);
|
||||
}
|
||||
return connection.invoke().just(RedisListAsyncCommands::lpop, key);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -388,19 +220,7 @@ class LettuceListCommands implements RedisListCommands {
|
||||
|
||||
Assert.notNull(key, "Key must not be null!");
|
||||
|
||||
try {
|
||||
if (isPipelined()) {
|
||||
pipeline(connection.newLettuceResult(getAsyncConnection().rpop(key)));
|
||||
return null;
|
||||
}
|
||||
if (isQueueing()) {
|
||||
transaction(connection.newLettuceResult(getAsyncConnection().rpop(key)));
|
||||
return null;
|
||||
}
|
||||
return getConnection().rpop(key);
|
||||
} catch (Exception ex) {
|
||||
throw convertLettuceAccessException(ex);
|
||||
}
|
||||
return connection.invoke().just(RedisListAsyncCommands::rpop, key);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -413,21 +233,8 @@ class LettuceListCommands implements RedisListCommands {
|
||||
Assert.notNull(keys, "Key must not be null!");
|
||||
Assert.noNullElements(keys, "Keys must not contain null elements!");
|
||||
|
||||
try {
|
||||
if (isPipelined()) {
|
||||
pipeline(connection.newLettuceResult(connection.getAsyncDedicatedConnection().blpop(timeout, keys),
|
||||
LettuceConverters.keyValueToBytesList()));
|
||||
return null;
|
||||
}
|
||||
if (isQueueing()) {
|
||||
transaction(connection.newLettuceResult(connection.getAsyncDedicatedConnection().blpop(timeout, keys),
|
||||
LettuceConverters.keyValueToBytesList()));
|
||||
return null;
|
||||
}
|
||||
return LettuceConverters.toBytesList(connection.getDedicatedConnection().blpop(timeout, keys));
|
||||
} catch (Exception ex) {
|
||||
throw convertLettuceAccessException(ex);
|
||||
}
|
||||
return connection.invoke(connection.getAsyncDedicatedConnection())
|
||||
.from(RedisListAsyncCommands::blpop, timeout, keys).get(LettuceConverters.keyValueToBytesList());
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -440,21 +247,8 @@ class LettuceListCommands implements RedisListCommands {
|
||||
Assert.notNull(keys, "Key must not be null!");
|
||||
Assert.noNullElements(keys, "Keys must not contain null elements!");
|
||||
|
||||
try {
|
||||
if (isPipelined()) {
|
||||
pipeline(connection.newLettuceResult(connection.getAsyncDedicatedConnection().brpop(timeout, keys),
|
||||
LettuceConverters.keyValueToBytesList()));
|
||||
return null;
|
||||
}
|
||||
if (isQueueing()) {
|
||||
transaction(connection.newLettuceResult(connection.getAsyncDedicatedConnection().brpop(timeout, keys),
|
||||
LettuceConverters.keyValueToBytesList()));
|
||||
return null;
|
||||
}
|
||||
return LettuceConverters.toBytesList(connection.getDedicatedConnection().brpop(timeout, keys));
|
||||
} catch (Exception ex) {
|
||||
throw convertLettuceAccessException(ex);
|
||||
}
|
||||
return connection.invoke(connection.getAsyncDedicatedConnection())
|
||||
.from(RedisListAsyncCommands::brpop, timeout, keys).get(LettuceConverters.keyValueToBytesList());
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -467,19 +261,7 @@ class LettuceListCommands implements RedisListCommands {
|
||||
Assert.notNull(srcKey, "Source key must not be null!");
|
||||
Assert.notNull(dstKey, "Destination key must not be null!");
|
||||
|
||||
try {
|
||||
if (isPipelined()) {
|
||||
pipeline(connection.newLettuceResult(getAsyncConnection().rpoplpush(srcKey, dstKey)));
|
||||
return null;
|
||||
}
|
||||
if (isQueueing()) {
|
||||
transaction(connection.newLettuceResult(getAsyncConnection().rpoplpush(srcKey, dstKey)));
|
||||
return null;
|
||||
}
|
||||
return getConnection().rpoplpush(srcKey, dstKey);
|
||||
} catch (Exception ex) {
|
||||
throw convertLettuceAccessException(ex);
|
||||
}
|
||||
return connection.invoke().just(RedisListAsyncCommands::rpoplpush, srcKey, dstKey);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -492,49 +274,8 @@ class LettuceListCommands implements RedisListCommands {
|
||||
Assert.notNull(srcKey, "Source key must not be null!");
|
||||
Assert.notNull(dstKey, "Destination key must not be null!");
|
||||
|
||||
try {
|
||||
if (isPipelined()) {
|
||||
pipeline(
|
||||
connection.newLettuceResult(connection.getAsyncDedicatedConnection().brpoplpush(timeout, srcKey, dstKey)));
|
||||
return null;
|
||||
}
|
||||
if (isQueueing()) {
|
||||
transaction(
|
||||
connection.newLettuceResult(connection.getAsyncDedicatedConnection().brpoplpush(timeout, srcKey, dstKey)));
|
||||
return null;
|
||||
}
|
||||
return connection.getDedicatedConnection().brpoplpush(timeout, srcKey, dstKey);
|
||||
} catch (Exception ex) {
|
||||
throw convertLettuceAccessException(ex);
|
||||
}
|
||||
}
|
||||
|
||||
private boolean isPipelined() {
|
||||
return connection.isPipelined();
|
||||
}
|
||||
|
||||
private boolean isQueueing() {
|
||||
return connection.isQueueing();
|
||||
}
|
||||
|
||||
private void pipeline(LettuceResult result) {
|
||||
connection.pipeline(result);
|
||||
}
|
||||
|
||||
private void transaction(LettuceResult result) {
|
||||
connection.transaction(result);
|
||||
}
|
||||
|
||||
private RedisClusterAsyncCommands<byte[], byte[]> getAsyncConnection() {
|
||||
return connection.getAsyncConnection();
|
||||
}
|
||||
|
||||
public RedisClusterCommands<byte[], byte[]> getConnection() {
|
||||
return connection.getConnection();
|
||||
}
|
||||
|
||||
private DataAccessException convertLettuceAccessException(Exception ex) {
|
||||
return connection.convertLettuceAccessException(ex);
|
||||
return connection.invoke(connection.getAsyncDedicatedConnection()).just(RedisListAsyncCommands::brpoplpush, timeout,
|
||||
srcKey, dstKey);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -15,14 +15,12 @@
|
||||
*/
|
||||
package org.springframework.data.redis.connection.lettuce;
|
||||
|
||||
import io.lettuce.core.cluster.api.async.RedisClusterAsyncCommands;
|
||||
import io.lettuce.core.cluster.api.sync.RedisClusterCommands;
|
||||
import io.lettuce.core.api.async.RedisScriptingAsyncCommands;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
import org.springframework.core.convert.converter.Converter;
|
||||
import org.springframework.dao.DataAccessException;
|
||||
import org.springframework.data.redis.connection.RedisScriptingCommands;
|
||||
import org.springframework.data.redis.connection.ReturnType;
|
||||
import org.springframework.util.Assert;
|
||||
@@ -45,20 +43,7 @@ class LettuceScriptingCommands implements RedisScriptingCommands {
|
||||
*/
|
||||
@Override
|
||||
public void scriptFlush() {
|
||||
|
||||
try {
|
||||
if (isPipelined()) {
|
||||
pipeline(connection.newLettuceStatusResult(getAsyncConnection().scriptFlush()));
|
||||
return;
|
||||
}
|
||||
if (isQueueing()) {
|
||||
transaction(connection.newLettuceStatusResult(getAsyncConnection().scriptFlush()));
|
||||
return;
|
||||
}
|
||||
getConnection().scriptFlush();
|
||||
} catch (Exception ex) {
|
||||
throw convertLettuceAccessException(ex);
|
||||
}
|
||||
connection.invoke().just(RedisScriptingAsyncCommands::scriptFlush);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -68,19 +53,11 @@ class LettuceScriptingCommands implements RedisScriptingCommands {
|
||||
@Override
|
||||
public void scriptKill() {
|
||||
|
||||
if (isQueueing()) {
|
||||
if (connection.isQueueing()) {
|
||||
throw new UnsupportedOperationException("Script kill not permitted in a transaction");
|
||||
}
|
||||
|
||||
try {
|
||||
if (isPipelined()) {
|
||||
pipeline(connection.newLettuceStatusResult(getAsyncConnection().scriptKill()));
|
||||
return;
|
||||
}
|
||||
getConnection().scriptKill();
|
||||
} catch (Exception ex) {
|
||||
throw convertLettuceAccessException(ex);
|
||||
}
|
||||
connection.invoke().just(RedisScriptingAsyncCommands::scriptKill);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -92,19 +69,7 @@ class LettuceScriptingCommands implements RedisScriptingCommands {
|
||||
|
||||
Assert.notNull(script, "Script must not be null!");
|
||||
|
||||
try {
|
||||
if (isPipelined()) {
|
||||
pipeline(connection.newLettuceResult(getAsyncConnection().scriptLoad(script)));
|
||||
return null;
|
||||
}
|
||||
if (isQueueing()) {
|
||||
transaction(connection.newLettuceResult(getAsyncConnection().scriptLoad(script)));
|
||||
return null;
|
||||
}
|
||||
return getConnection().scriptLoad(script);
|
||||
} catch (Exception ex) {
|
||||
throw convertLettuceAccessException(ex);
|
||||
}
|
||||
return connection.invoke().just(RedisScriptingAsyncCommands::scriptLoad, script);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -117,19 +82,7 @@ class LettuceScriptingCommands implements RedisScriptingCommands {
|
||||
Assert.notNull(scriptSha1, "Script digests must not be null!");
|
||||
Assert.noNullElements(scriptSha1, "Script digests must not contain null elements!");
|
||||
|
||||
try {
|
||||
if (isPipelined()) {
|
||||
pipeline(connection.newLettuceResult(getAsyncConnection().scriptExists(scriptSha1)));
|
||||
return null;
|
||||
}
|
||||
if (isQueueing()) {
|
||||
transaction(connection.newLettuceResult(getAsyncConnection().scriptExists(scriptSha1)));
|
||||
return null;
|
||||
}
|
||||
return getConnection().scriptExists(scriptSha1);
|
||||
} catch (Exception ex) {
|
||||
throw convertLettuceAccessException(ex);
|
||||
}
|
||||
return connection.invoke().just(RedisScriptingAsyncCommands::scriptExists, scriptSha1);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -141,27 +94,14 @@ class LettuceScriptingCommands implements RedisScriptingCommands {
|
||||
|
||||
Assert.notNull(script, "Script must not be null!");
|
||||
|
||||
try {
|
||||
byte[][] keys = extractScriptKeys(numKeys, keysAndArgs);
|
||||
byte[][] args = extractScriptArgs(numKeys, keysAndArgs);
|
||||
String convertedScript = LettuceConverters.toString(script);
|
||||
if (isPipelined()) {
|
||||
pipeline(connection.newLettuceResult(
|
||||
getAsyncConnection().eval(convertedScript, LettuceConverters.toScriptOutputType(returnType), keys, args),
|
||||
new LettuceEvalResultsConverter<T>(returnType)));
|
||||
return null;
|
||||
}
|
||||
if (isQueueing()) {
|
||||
transaction(connection.newLettuceResult(
|
||||
getAsyncConnection().eval(convertedScript, LettuceConverters.toScriptOutputType(returnType), keys, args),
|
||||
new LettuceEvalResultsConverter<T>(returnType)));
|
||||
return null;
|
||||
}
|
||||
return new LettuceEvalResultsConverter<T>(returnType)
|
||||
.convert(getConnection().eval(convertedScript, LettuceConverters.toScriptOutputType(returnType), keys, args));
|
||||
} catch (Exception ex) {
|
||||
throw convertLettuceAccessException(ex);
|
||||
}
|
||||
byte[][] keys = extractScriptKeys(numKeys, keysAndArgs);
|
||||
byte[][] args = extractScriptArgs(numKeys, keysAndArgs);
|
||||
String convertedScript = LettuceConverters.toString(script);
|
||||
|
||||
return connection
|
||||
.invoke().from(RedisScriptingAsyncCommands::eval, convertedScript,
|
||||
LettuceConverters.toScriptOutputType(returnType), keys, args)
|
||||
.get(new LettuceEvalResultsConverter<T>(returnType));
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -173,27 +113,13 @@ class LettuceScriptingCommands implements RedisScriptingCommands {
|
||||
|
||||
Assert.notNull(scriptSha1, "Script digest must not be null!");
|
||||
|
||||
try {
|
||||
byte[][] keys = extractScriptKeys(numKeys, keysAndArgs);
|
||||
byte[][] args = extractScriptArgs(numKeys, keysAndArgs);
|
||||
byte[][] keys = extractScriptKeys(numKeys, keysAndArgs);
|
||||
byte[][] args = extractScriptArgs(numKeys, keysAndArgs);
|
||||
|
||||
if (isPipelined()) {
|
||||
pipeline(connection.newLettuceResult(
|
||||
getAsyncConnection().evalsha(scriptSha1, LettuceConverters.toScriptOutputType(returnType), keys, args),
|
||||
new LettuceEvalResultsConverter<T>(returnType)));
|
||||
return null;
|
||||
}
|
||||
if (isQueueing()) {
|
||||
transaction(connection.newLettuceResult(
|
||||
getAsyncConnection().evalsha(scriptSha1, LettuceConverters.toScriptOutputType(returnType), keys, args),
|
||||
new LettuceEvalResultsConverter<T>(returnType)));
|
||||
return null;
|
||||
}
|
||||
return new LettuceEvalResultsConverter<T>(returnType)
|
||||
.convert(getConnection().evalsha(scriptSha1, LettuceConverters.toScriptOutputType(returnType), keys, args));
|
||||
} catch (Exception ex) {
|
||||
throw convertLettuceAccessException(ex);
|
||||
}
|
||||
return connection
|
||||
.invoke().from(RedisScriptingAsyncCommands::evalsha, scriptSha1,
|
||||
LettuceConverters.toScriptOutputType(returnType), keys, args)
|
||||
.get(new LettuceEvalResultsConverter<T>(returnType));
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -208,34 +134,6 @@ class LettuceScriptingCommands implements RedisScriptingCommands {
|
||||
return evalSha(LettuceConverters.toString(scriptSha1), returnType, numKeys, keysAndArgs);
|
||||
}
|
||||
|
||||
private boolean isPipelined() {
|
||||
return connection.isPipelined();
|
||||
}
|
||||
|
||||
private boolean isQueueing() {
|
||||
return connection.isQueueing();
|
||||
}
|
||||
|
||||
private void pipeline(LettuceResult result) {
|
||||
connection.pipeline(result);
|
||||
}
|
||||
|
||||
private void transaction(LettuceResult result) {
|
||||
connection.transaction(result);
|
||||
}
|
||||
|
||||
private RedisClusterAsyncCommands<byte[], byte[]> getAsyncConnection() {
|
||||
return connection.getAsyncConnection();
|
||||
}
|
||||
|
||||
public RedisClusterCommands<byte[], byte[]> getConnection() {
|
||||
return connection.getConnection();
|
||||
}
|
||||
|
||||
private DataAccessException convertLettuceAccessException(Exception ex) {
|
||||
return connection.convertLettuceAccessException(ex);
|
||||
}
|
||||
|
||||
private static byte[][] extractScriptKeys(int numKeys, byte[]... keysAndArgs) {
|
||||
if (numKeys > 0) {
|
||||
return Arrays.copyOfRange(keysAndArgs, 0, numKeys);
|
||||
@@ -251,7 +149,8 @@ class LettuceScriptingCommands implements RedisScriptingCommands {
|
||||
}
|
||||
|
||||
private class LettuceEvalResultsConverter<T> implements Converter<Object, T> {
|
||||
private ReturnType returnType;
|
||||
|
||||
private final ReturnType returnType;
|
||||
|
||||
public LettuceEvalResultsConverter(ReturnType returnType) {
|
||||
this.returnType = returnType;
|
||||
@@ -263,7 +162,7 @@ class LettuceScriptingCommands implements RedisScriptingCommands {
|
||||
List resultList = (List) source;
|
||||
for (Object obj : resultList) {
|
||||
if (obj instanceof Exception) {
|
||||
throw convertLettuceAccessException((Exception) obj);
|
||||
throw connection.convertLettuceAccessException((Exception) obj);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -15,16 +15,19 @@
|
||||
*/
|
||||
package org.springframework.data.redis.connection.lettuce;
|
||||
|
||||
import io.lettuce.core.cluster.api.async.RedisClusterAsyncCommands;
|
||||
import io.lettuce.core.LettuceFutures;
|
||||
import io.lettuce.core.RedisFuture;
|
||||
import io.lettuce.core.api.async.RedisKeyAsyncCommands;
|
||||
import io.lettuce.core.api.async.RedisServerAsyncCommands;
|
||||
import io.lettuce.core.cluster.api.sync.RedisClusterCommands;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Properties;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import org.springframework.dao.DataAccessException;
|
||||
import org.springframework.data.redis.connection.RedisNode;
|
||||
import org.springframework.data.redis.connection.RedisServerCommands;
|
||||
import org.springframework.data.redis.connection.convert.Converters;
|
||||
import org.springframework.data.redis.core.types.RedisClientInfo;
|
||||
import org.springframework.lang.Nullable;
|
||||
import org.springframework.util.Assert;
|
||||
@@ -47,20 +50,7 @@ class LettuceServerCommands implements RedisServerCommands {
|
||||
*/
|
||||
@Override
|
||||
public void bgReWriteAof() {
|
||||
|
||||
try {
|
||||
if (isPipelined()) {
|
||||
pipeline(connection.newLettuceStatusResult(getAsyncConnection().bgrewriteaof()));
|
||||
return;
|
||||
}
|
||||
if (isQueueing()) {
|
||||
transaction(connection.newLettuceStatusResult(getAsyncConnection().bgrewriteaof()));
|
||||
return;
|
||||
}
|
||||
getConnection().bgrewriteaof();
|
||||
} catch (Exception ex) {
|
||||
throw convertLettuceAccessException(ex);
|
||||
}
|
||||
connection.invokeStatus().just(RedisServerAsyncCommands::bgrewriteaof);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -69,20 +59,7 @@ class LettuceServerCommands implements RedisServerCommands {
|
||||
*/
|
||||
@Override
|
||||
public void bgSave() {
|
||||
|
||||
try {
|
||||
if (isPipelined()) {
|
||||
pipeline(connection.newLettuceStatusResult(getAsyncConnection().bgsave()));
|
||||
return;
|
||||
}
|
||||
if (isQueueing()) {
|
||||
transaction(connection.newLettuceStatusResult(getAsyncConnection().bgsave()));
|
||||
return;
|
||||
}
|
||||
getConnection().bgsave();
|
||||
} catch (Exception ex) {
|
||||
throw convertLettuceAccessException(ex);
|
||||
}
|
||||
connection.invokeStatus().just(RedisServerAsyncCommands::bgsave);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -91,20 +68,7 @@ class LettuceServerCommands implements RedisServerCommands {
|
||||
*/
|
||||
@Override
|
||||
public Long lastSave() {
|
||||
|
||||
try {
|
||||
if (isPipelined()) {
|
||||
pipeline(connection.newLettuceResult(getAsyncConnection().lastsave(), LettuceConverters.dateToLong()));
|
||||
return null;
|
||||
}
|
||||
if (isQueueing()) {
|
||||
transaction(connection.newLettuceResult(getAsyncConnection().lastsave(), LettuceConverters.dateToLong()));
|
||||
return null;
|
||||
}
|
||||
return LettuceConverters.toLong(getConnection().lastsave());
|
||||
} catch (Exception ex) {
|
||||
throw convertLettuceAccessException(ex);
|
||||
}
|
||||
return connection.invoke().from(RedisServerAsyncCommands::lastsave).get(LettuceConverters.dateToLong());
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -113,20 +77,7 @@ class LettuceServerCommands implements RedisServerCommands {
|
||||
*/
|
||||
@Override
|
||||
public void save() {
|
||||
|
||||
try {
|
||||
if (isPipelined()) {
|
||||
pipeline(connection.newLettuceStatusResult(getAsyncConnection().save()));
|
||||
return;
|
||||
}
|
||||
if (isQueueing()) {
|
||||
transaction(connection.newLettuceStatusResult(getAsyncConnection().save()));
|
||||
return;
|
||||
}
|
||||
getConnection().save();
|
||||
} catch (Exception ex) {
|
||||
throw convertLettuceAccessException(ex);
|
||||
}
|
||||
connection.invokeStatus().just(RedisServerAsyncCommands::save);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -135,20 +86,7 @@ class LettuceServerCommands implements RedisServerCommands {
|
||||
*/
|
||||
@Override
|
||||
public Long dbSize() {
|
||||
|
||||
try {
|
||||
if (isPipelined()) {
|
||||
pipeline(connection.newLettuceResult(getAsyncConnection().dbsize()));
|
||||
return null;
|
||||
}
|
||||
if (isQueueing()) {
|
||||
transaction(connection.newLettuceResult(getAsyncConnection().dbsize()));
|
||||
return null;
|
||||
}
|
||||
return getConnection().dbsize();
|
||||
} catch (Exception ex) {
|
||||
throw convertLettuceAccessException(ex);
|
||||
}
|
||||
return connection.invoke().just(RedisServerAsyncCommands::dbsize);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -157,20 +95,7 @@ class LettuceServerCommands implements RedisServerCommands {
|
||||
*/
|
||||
@Override
|
||||
public void flushDb() {
|
||||
|
||||
try {
|
||||
if (isPipelined()) {
|
||||
pipeline(connection.newLettuceStatusResult(getAsyncConnection().flushdb()));
|
||||
return;
|
||||
}
|
||||
if (isQueueing()) {
|
||||
transaction(connection.newLettuceStatusResult(getAsyncConnection().flushdb()));
|
||||
return;
|
||||
}
|
||||
getConnection().flushdb();
|
||||
} catch (Exception ex) {
|
||||
throw convertLettuceAccessException(ex);
|
||||
}
|
||||
connection.invokeStatus().just(RedisServerAsyncCommands::flushdb);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -179,20 +104,7 @@ class LettuceServerCommands implements RedisServerCommands {
|
||||
*/
|
||||
@Override
|
||||
public void flushAll() {
|
||||
|
||||
try {
|
||||
if (isPipelined()) {
|
||||
pipeline(connection.newLettuceStatusResult(getAsyncConnection().flushall()));
|
||||
return;
|
||||
}
|
||||
if (isQueueing()) {
|
||||
transaction(connection.newLettuceResult(getAsyncConnection().flushall()));
|
||||
return;
|
||||
}
|
||||
getConnection().flushall();
|
||||
} catch (Exception ex) {
|
||||
throw convertLettuceAccessException(ex);
|
||||
}
|
||||
connection.invokeStatus().just(RedisServerAsyncCommands::flushall);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -201,20 +113,7 @@ class LettuceServerCommands implements RedisServerCommands {
|
||||
*/
|
||||
@Override
|
||||
public Properties info() {
|
||||
|
||||
try {
|
||||
if (isPipelined()) {
|
||||
pipeline(connection.newLettuceResult(getAsyncConnection().info(), LettuceConverters.stringToProps()));
|
||||
return null;
|
||||
}
|
||||
if (isQueueing()) {
|
||||
transaction(connection.newLettuceResult(getAsyncConnection().info(), LettuceConverters.stringToProps()));
|
||||
return null;
|
||||
}
|
||||
return LettuceConverters.toProperties(getConnection().info());
|
||||
} catch (Exception ex) {
|
||||
throw convertLettuceAccessException(ex);
|
||||
}
|
||||
return connection.invoke().from(RedisServerAsyncCommands::info).get(LettuceConverters.stringToProps());
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -226,19 +125,7 @@ class LettuceServerCommands implements RedisServerCommands {
|
||||
|
||||
Assert.hasText(section, "Section must not be null or empty!");
|
||||
|
||||
try {
|
||||
if (isPipelined()) {
|
||||
pipeline(connection.newLettuceResult(getAsyncConnection().info(section), LettuceConverters.stringToProps()));
|
||||
return null;
|
||||
}
|
||||
if (isQueueing()) {
|
||||
transaction(connection.newLettuceResult(getAsyncConnection().info(section), LettuceConverters.stringToProps()));
|
||||
return null;
|
||||
}
|
||||
return LettuceConverters.toProperties(getConnection().info(section));
|
||||
} catch (Exception ex) {
|
||||
throw convertLettuceAccessException(ex);
|
||||
}
|
||||
return connection.invoke().from(RedisServerAsyncCommands::info, section).get(LettuceConverters.stringToProps());
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -247,16 +134,12 @@ class LettuceServerCommands implements RedisServerCommands {
|
||||
*/
|
||||
@Override
|
||||
public void shutdown() {
|
||||
connection.invokeStatus().just(it -> {
|
||||
|
||||
try {
|
||||
if (isPipelined()) {
|
||||
getAsyncConnection().shutdown(true);
|
||||
return;
|
||||
}
|
||||
getConnection().shutdown(true);
|
||||
} catch (Exception ex) {
|
||||
throw convertLettuceAccessException(ex);
|
||||
}
|
||||
it.shutdown(true);
|
||||
|
||||
return new CompletedRedisFuture<>(null);
|
||||
});
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -272,15 +155,13 @@ class LettuceServerCommands implements RedisServerCommands {
|
||||
}
|
||||
|
||||
boolean save = ShutdownOption.SAVE.equals(option);
|
||||
try {
|
||||
if (isPipelined()) {
|
||||
getAsyncConnection().shutdown(save);
|
||||
return;
|
||||
}
|
||||
getConnection().shutdown(save);
|
||||
} catch (Exception ex) {
|
||||
throw convertLettuceAccessException(ex);
|
||||
}
|
||||
|
||||
connection.invokeStatus().just(it -> {
|
||||
|
||||
it.shutdown(save);
|
||||
|
||||
return new CompletedRedisFuture<>(null);
|
||||
});
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -292,21 +173,8 @@ class LettuceServerCommands implements RedisServerCommands {
|
||||
|
||||
Assert.hasText(pattern, "Pattern must not be null or empty!");
|
||||
|
||||
try {
|
||||
if (isPipelined()) {
|
||||
pipeline(connection.newLettuceResult(getAsyncConnection().configGet(pattern),
|
||||
Converters.mapToPropertiesConverter()));
|
||||
return null;
|
||||
}
|
||||
if (isQueueing()) {
|
||||
transaction(connection.newLettuceResult(getAsyncConnection().configGet(pattern),
|
||||
Converters.mapToPropertiesConverter()));
|
||||
return null;
|
||||
}
|
||||
return Converters.toProperties(getConnection().configGet(pattern));
|
||||
} catch (Exception ex) {
|
||||
throw convertLettuceAccessException(ex);
|
||||
}
|
||||
return connection.invoke().from(RedisServerAsyncCommands::configGet, pattern)
|
||||
.get(LettuceConverters.mapToPropertiesConverter());
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -319,19 +187,8 @@ class LettuceServerCommands implements RedisServerCommands {
|
||||
Assert.hasText(param, "Parameter must not be null or empty!");
|
||||
Assert.hasText(value, "Value must not be null or empty!");
|
||||
|
||||
try {
|
||||
if (isPipelined()) {
|
||||
pipeline(connection.newLettuceStatusResult(getAsyncConnection().configSet(param, value)));
|
||||
return;
|
||||
}
|
||||
if (isQueueing()) {
|
||||
transaction(connection.newLettuceStatusResult(getAsyncConnection().configSet(param, value)));
|
||||
return;
|
||||
}
|
||||
getConnection().configSet(param, value);
|
||||
} catch (Exception ex) {
|
||||
throw convertLettuceAccessException(ex);
|
||||
}
|
||||
connection.invokeStatus().just(RedisServerAsyncCommands::configSet, param, value);
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -340,20 +197,7 @@ class LettuceServerCommands implements RedisServerCommands {
|
||||
*/
|
||||
@Override
|
||||
public void resetConfigStats() {
|
||||
|
||||
try {
|
||||
if (isPipelined()) {
|
||||
pipeline(connection.newLettuceStatusResult(getAsyncConnection().configResetstat()));
|
||||
return;
|
||||
}
|
||||
if (isQueueing()) {
|
||||
transaction(connection.newLettuceStatusResult(getAsyncConnection().configResetstat()));
|
||||
return;
|
||||
}
|
||||
getConnection().configResetstat();
|
||||
} catch (Exception ex) {
|
||||
throw convertLettuceAccessException(ex);
|
||||
}
|
||||
connection.invokeStatus().just(RedisServerAsyncCommands::configResetstat);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -362,20 +206,7 @@ class LettuceServerCommands implements RedisServerCommands {
|
||||
*/
|
||||
@Override
|
||||
public Long time() {
|
||||
|
||||
try {
|
||||
if (isPipelined()) {
|
||||
pipeline(connection.newLettuceResult(getAsyncConnection().time(), LettuceConverters.toTimeConverter()));
|
||||
return null;
|
||||
}
|
||||
if (isQueueing()) {
|
||||
transaction(connection.newLettuceResult(getAsyncConnection().time(), LettuceConverters.toTimeConverter()));
|
||||
return null;
|
||||
}
|
||||
return LettuceConverters.toTimeConverter().convert(getConnection().time());
|
||||
} catch (Exception ex) {
|
||||
throw convertLettuceAccessException(ex);
|
||||
}
|
||||
return connection.invoke().from(RedisServerAsyncCommands::time).get(LettuceConverters.toTimeConverter());
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -388,15 +219,8 @@ class LettuceServerCommands implements RedisServerCommands {
|
||||
Assert.hasText(host, "Host for 'CLIENT KILL' must not be 'null' or 'empty'.");
|
||||
|
||||
String client = String.format("%s:%s", host, port);
|
||||
try {
|
||||
if (isPipelined()) {
|
||||
pipeline(connection.newLettuceStatusResult(getAsyncConnection().clientKill(client)));
|
||||
return;
|
||||
}
|
||||
getConnection().clientKill(client);
|
||||
} catch (Exception e) {
|
||||
throw convertLettuceAccessException(e);
|
||||
}
|
||||
|
||||
connection.invoke().just(RedisServerAsyncCommands::clientKill, client);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -408,16 +232,7 @@ class LettuceServerCommands implements RedisServerCommands {
|
||||
|
||||
Assert.notNull(name, "Name must not be null!");
|
||||
|
||||
if (isQueueing()) {
|
||||
pipeline(connection.newLettuceStatusResult(getAsyncConnection().clientSetname(name)));
|
||||
return;
|
||||
}
|
||||
if (isQueueing()) {
|
||||
transaction(connection.newLettuceStatusResult(getAsyncConnection().clientSetname(name)));
|
||||
return;
|
||||
}
|
||||
|
||||
getAsyncConnection().clientSetname(name);
|
||||
connection.invoke().just(RedisServerAsyncCommands::clientSetname, name);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -426,21 +241,7 @@ class LettuceServerCommands implements RedisServerCommands {
|
||||
*/
|
||||
@Override
|
||||
public String getClientName() {
|
||||
|
||||
try {
|
||||
if (isPipelined()) {
|
||||
pipeline(connection.newLettuceResult(getAsyncConnection().clientGetname(), LettuceConverters.bytesToString()));
|
||||
return null;
|
||||
}
|
||||
if (isQueueing()) {
|
||||
transaction(
|
||||
connection.newLettuceResult(getAsyncConnection().clientGetname(), LettuceConverters.bytesToString()));
|
||||
return null;
|
||||
}
|
||||
return LettuceConverters.toString(getConnection().clientGetname());
|
||||
} catch (Exception ex) {
|
||||
throw convertLettuceAccessException(ex);
|
||||
}
|
||||
return connection.invoke().from(RedisServerAsyncCommands::clientGetname).get(LettuceConverters.bytesToString());
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -450,16 +251,12 @@ class LettuceServerCommands implements RedisServerCommands {
|
||||
@Override
|
||||
public List<RedisClientInfo> getClientList() {
|
||||
|
||||
if (isPipelined()) {
|
||||
if (connection.isPipelined()) {
|
||||
throw new UnsupportedOperationException("Cannot be called in pipeline mode.");
|
||||
}
|
||||
if (isQueueing()) {
|
||||
transaction(connection.newLettuceResult(getAsyncConnection().clientList(),
|
||||
LettuceConverters.stringToRedisClientListConverter()));
|
||||
return null;
|
||||
}
|
||||
|
||||
return LettuceConverters.toListOfRedisClientInformation(getConnection().clientList());
|
||||
return connection.invoke().from(RedisServerAsyncCommands::clientList)
|
||||
.get(LettuceConverters.stringToRedisClientListConverter());
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -471,19 +268,7 @@ class LettuceServerCommands implements RedisServerCommands {
|
||||
|
||||
Assert.hasText(host, "Host must not be null for 'SLAVEOF' command.");
|
||||
|
||||
try {
|
||||
if (isPipelined()) {
|
||||
pipeline(connection.newLettuceStatusResult(getAsyncConnection().slaveof(host, port)));
|
||||
return;
|
||||
}
|
||||
if (isQueueing()) {
|
||||
transaction(connection.newLettuceResult(getAsyncConnection().slaveof(host, port)));
|
||||
return;
|
||||
}
|
||||
getConnection().slaveof(host, port);
|
||||
} catch (Exception ex) {
|
||||
throw convertLettuceAccessException(ex);
|
||||
}
|
||||
connection.invoke().just(RedisServerAsyncCommands::slaveof, host, port);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -492,20 +277,7 @@ class LettuceServerCommands implements RedisServerCommands {
|
||||
*/
|
||||
@Override
|
||||
public void slaveOfNoOne() {
|
||||
|
||||
try {
|
||||
if (isPipelined()) {
|
||||
pipeline(connection.newLettuceStatusResult(getAsyncConnection().slaveofNoOne()));
|
||||
return;
|
||||
}
|
||||
if (isQueueing()) {
|
||||
transaction(connection.newLettuceResult(getAsyncConnection().slaveofNoOne()));
|
||||
return;
|
||||
}
|
||||
getConnection().slaveofNoOne();
|
||||
} catch (Exception ex) {
|
||||
throw convertLettuceAccessException(ex);
|
||||
}
|
||||
connection.invoke().just(RedisServerAsyncCommands::slaveofNoOne);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -527,48 +299,27 @@ class LettuceServerCommands implements RedisServerCommands {
|
||||
Assert.notNull(key, "Key must not be null!");
|
||||
Assert.notNull(target, "Target node must not be null!");
|
||||
|
||||
try {
|
||||
if (isPipelined()) {
|
||||
pipeline(connection
|
||||
.newLettuceResult(getAsyncConnection().migrate(target.getHost(), target.getPort(), key, dbIndex, timeout)));
|
||||
return;
|
||||
}
|
||||
if (isQueueing()) {
|
||||
transaction(connection
|
||||
.newLettuceResult(getAsyncConnection().migrate(target.getHost(), target.getPort(), key, dbIndex, timeout)));
|
||||
return;
|
||||
}
|
||||
getConnection().migrate(target.getHost(), target.getPort(), key, dbIndex, timeout);
|
||||
} catch (Exception ex) {
|
||||
throw convertLettuceAccessException(ex);
|
||||
}
|
||||
}
|
||||
|
||||
private boolean isPipelined() {
|
||||
return connection.isPipelined();
|
||||
}
|
||||
|
||||
private boolean isQueueing() {
|
||||
return connection.isQueueing();
|
||||
}
|
||||
|
||||
private void pipeline(LettuceResult<?, ?> result) {
|
||||
connection.pipeline(result);
|
||||
}
|
||||
|
||||
private void transaction(LettuceResult<?, ?> result) {
|
||||
connection.transaction(result);
|
||||
}
|
||||
|
||||
private RedisClusterAsyncCommands<byte[], byte[]> getAsyncConnection() {
|
||||
return connection.getAsyncConnection();
|
||||
connection.invoke().just(RedisKeyAsyncCommands::migrate, target.getHost(), target.getPort(), key, dbIndex, timeout);
|
||||
}
|
||||
|
||||
public RedisClusterCommands<byte[], byte[]> getConnection() {
|
||||
return connection.getConnection();
|
||||
}
|
||||
|
||||
private DataAccessException convertLettuceAccessException(Exception ex) {
|
||||
return connection.convertLettuceAccessException(ex);
|
||||
static class CompletedRedisFuture<T> extends CompletableFuture<T> implements RedisFuture<T> {
|
||||
|
||||
public CompletedRedisFuture(T value) {
|
||||
complete(value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getError() {
|
||||
return "";
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean await(long timeout, TimeUnit unit) throws InterruptedException {
|
||||
return LettuceFutures.awaitAll(timeout, unit, this);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -17,15 +17,13 @@ package org.springframework.data.redis.connection.lettuce;
|
||||
|
||||
import io.lettuce.core.ScanArgs;
|
||||
import io.lettuce.core.ValueScanCursor;
|
||||
import io.lettuce.core.cluster.api.async.RedisClusterAsyncCommands;
|
||||
import io.lettuce.core.api.async.RedisSetAsyncCommands;
|
||||
import io.lettuce.core.cluster.api.sync.RedisClusterCommands;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
import org.springframework.core.convert.converter.Converter;
|
||||
import org.springframework.dao.DataAccessException;
|
||||
import org.springframework.data.redis.connection.RedisSetCommands;
|
||||
import org.springframework.data.redis.core.Cursor;
|
||||
import org.springframework.data.redis.core.KeyBoundCursor;
|
||||
@@ -57,19 +55,7 @@ class LettuceSetCommands implements RedisSetCommands {
|
||||
Assert.notNull(values, "Values must not be null!");
|
||||
Assert.noNullElements(values, "Values must not contain null elements!");
|
||||
|
||||
try {
|
||||
if (isPipelined()) {
|
||||
pipeline(connection.newLettuceResult(getAsyncConnection().sadd(key, values)));
|
||||
return null;
|
||||
}
|
||||
if (isQueueing()) {
|
||||
transaction(connection.newLettuceResult(getAsyncConnection().sadd(key, values)));
|
||||
return null;
|
||||
}
|
||||
return getConnection().sadd(key, values);
|
||||
} catch (Exception ex) {
|
||||
throw convertLettuceAccessException(ex);
|
||||
}
|
||||
return connection.invoke().just(RedisSetAsyncCommands::sadd, key, values);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -81,19 +67,7 @@ class LettuceSetCommands implements RedisSetCommands {
|
||||
|
||||
Assert.notNull(key, "Key must not be null!");
|
||||
|
||||
try {
|
||||
if (isPipelined()) {
|
||||
pipeline(connection.newLettuceResult(getAsyncConnection().scard(key)));
|
||||
return null;
|
||||
}
|
||||
if (isQueueing()) {
|
||||
transaction(connection.newLettuceResult(getAsyncConnection().scard(key)));
|
||||
return null;
|
||||
}
|
||||
return getConnection().scard(key);
|
||||
} catch (Exception ex) {
|
||||
throw convertLettuceAccessException(ex);
|
||||
}
|
||||
return connection.invoke().just(RedisSetAsyncCommands::scard, key);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -106,19 +80,7 @@ class LettuceSetCommands implements RedisSetCommands {
|
||||
Assert.notNull(keys, "Keys must not be null!");
|
||||
Assert.noNullElements(keys, "Keys must not contain null elements!");
|
||||
|
||||
try {
|
||||
if (isPipelined()) {
|
||||
pipeline(connection.newLettuceResult(getAsyncConnection().sdiff(keys)));
|
||||
return null;
|
||||
}
|
||||
if (isQueueing()) {
|
||||
transaction(connection.newLettuceResult(getAsyncConnection().sdiff(keys)));
|
||||
return null;
|
||||
}
|
||||
return getConnection().sdiff(keys);
|
||||
} catch (Exception ex) {
|
||||
throw convertLettuceAccessException(ex);
|
||||
}
|
||||
return connection.invoke().just(RedisSetAsyncCommands::sdiff, keys);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -132,19 +94,7 @@ class LettuceSetCommands implements RedisSetCommands {
|
||||
Assert.notNull(keys, "Source keys must not be null!");
|
||||
Assert.noNullElements(keys, "Source keys must not contain null elements!");
|
||||
|
||||
try {
|
||||
if (isPipelined()) {
|
||||
pipeline(connection.newLettuceResult(getAsyncConnection().sdiffstore(destKey, keys)));
|
||||
return null;
|
||||
}
|
||||
if (isQueueing()) {
|
||||
transaction(connection.newLettuceResult(getAsyncConnection().sdiffstore(destKey, keys)));
|
||||
return null;
|
||||
}
|
||||
return getConnection().sdiffstore(destKey, keys);
|
||||
} catch (Exception ex) {
|
||||
throw convertLettuceAccessException(ex);
|
||||
}
|
||||
return connection.invoke().just(RedisSetAsyncCommands::sdiffstore, destKey, keys);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -157,19 +107,7 @@ class LettuceSetCommands implements RedisSetCommands {
|
||||
Assert.notNull(keys, "Keys must not be null!");
|
||||
Assert.noNullElements(keys, "Keys must not contain null elements!");
|
||||
|
||||
try {
|
||||
if (isPipelined()) {
|
||||
pipeline(connection.newLettuceResult(getAsyncConnection().sinter(keys)));
|
||||
return null;
|
||||
}
|
||||
if (isQueueing()) {
|
||||
transaction(connection.newLettuceResult(getAsyncConnection().sinter(keys)));
|
||||
return null;
|
||||
}
|
||||
return getConnection().sinter(keys);
|
||||
} catch (Exception ex) {
|
||||
throw convertLettuceAccessException(ex);
|
||||
}
|
||||
return connection.invoke().just(RedisSetAsyncCommands::sinter, keys);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -183,19 +121,7 @@ class LettuceSetCommands implements RedisSetCommands {
|
||||
Assert.notNull(keys, "Source keys must not be null!");
|
||||
Assert.noNullElements(keys, "Source keys must not contain null elements!");
|
||||
|
||||
try {
|
||||
if (isPipelined()) {
|
||||
pipeline(connection.newLettuceResult(getAsyncConnection().sinterstore(destKey, keys)));
|
||||
return null;
|
||||
}
|
||||
if (isQueueing()) {
|
||||
transaction(connection.newLettuceResult(getAsyncConnection().sinterstore(destKey, keys)));
|
||||
return null;
|
||||
}
|
||||
return getConnection().sinterstore(destKey, keys);
|
||||
} catch (Exception ex) {
|
||||
throw convertLettuceAccessException(ex);
|
||||
}
|
||||
return connection.invoke().just(RedisSetAsyncCommands::sinterstore, destKey, keys);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -208,19 +134,7 @@ class LettuceSetCommands implements RedisSetCommands {
|
||||
Assert.notNull(key, "Key must not be null!");
|
||||
Assert.notNull(value, "Value must not be null!");
|
||||
|
||||
try {
|
||||
if (isPipelined()) {
|
||||
pipeline(connection.newLettuceResult(getAsyncConnection().sismember(key, value)));
|
||||
return null;
|
||||
}
|
||||
if (isQueueing()) {
|
||||
transaction(connection.newLettuceResult(getAsyncConnection().sismember(key, value)));
|
||||
return null;
|
||||
}
|
||||
return getConnection().sismember(key, value);
|
||||
} catch (Exception ex) {
|
||||
throw convertLettuceAccessException(ex);
|
||||
}
|
||||
return connection.invoke().just(RedisSetAsyncCommands::sismember, key, value);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -232,19 +146,7 @@ class LettuceSetCommands implements RedisSetCommands {
|
||||
|
||||
Assert.notNull(key, "Key must not be null!");
|
||||
|
||||
try {
|
||||
if (isPipelined()) {
|
||||
pipeline(connection.newLettuceResult(getAsyncConnection().smembers(key)));
|
||||
return null;
|
||||
}
|
||||
if (isQueueing()) {
|
||||
transaction(connection.newLettuceResult(getAsyncConnection().smembers(key)));
|
||||
return null;
|
||||
}
|
||||
return getConnection().smembers(key);
|
||||
} catch (Exception ex) {
|
||||
throw convertLettuceAccessException(ex);
|
||||
}
|
||||
return connection.invoke().just(RedisSetAsyncCommands::smembers, key);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -258,19 +160,7 @@ class LettuceSetCommands implements RedisSetCommands {
|
||||
Assert.notNull(destKey, "Destination key must not be null!");
|
||||
Assert.notNull(value, "Value must not be null!");
|
||||
|
||||
try {
|
||||
if (isPipelined()) {
|
||||
pipeline(connection.newLettuceResult(getAsyncConnection().smove(srcKey, destKey, value)));
|
||||
return null;
|
||||
}
|
||||
if (isQueueing()) {
|
||||
transaction(connection.newLettuceResult(getAsyncConnection().smove(srcKey, destKey, value)));
|
||||
return null;
|
||||
}
|
||||
return getConnection().smove(srcKey, destKey, value);
|
||||
} catch (Exception ex) {
|
||||
throw convertLettuceAccessException(ex);
|
||||
}
|
||||
return connection.invoke().just(RedisSetAsyncCommands::smove, srcKey, destKey, value);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -282,19 +172,7 @@ class LettuceSetCommands implements RedisSetCommands {
|
||||
|
||||
Assert.notNull(key, "Key must not be null!");
|
||||
|
||||
try {
|
||||
if (isPipelined()) {
|
||||
pipeline(connection.newLettuceResult(getAsyncConnection().spop(key)));
|
||||
return null;
|
||||
}
|
||||
if (isQueueing()) {
|
||||
transaction(connection.newLettuceResult(getAsyncConnection().spop(key)));
|
||||
return null;
|
||||
}
|
||||
return getConnection().spop(key);
|
||||
} catch (Exception ex) {
|
||||
throw convertLettuceAccessException(ex);
|
||||
}
|
||||
return connection.invoke().just(RedisSetAsyncCommands::spop, key);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -306,20 +184,7 @@ class LettuceSetCommands implements RedisSetCommands {
|
||||
|
||||
Assert.notNull(key, "Key must not be null!");
|
||||
|
||||
try {
|
||||
if (isPipelined()) {
|
||||
pipeline(connection.newLettuceResult(getAsyncConnection().spop(key, count), ArrayList::new));
|
||||
return null;
|
||||
}
|
||||
if (isQueueing()) {
|
||||
transaction(connection.newLettuceResult(getAsyncConnection().spop(key, count),
|
||||
(Converter<Set<byte[]>, List<byte[]>>) ArrayList::new));
|
||||
return null;
|
||||
}
|
||||
return new ArrayList<>(getConnection().spop(key, count));
|
||||
} catch (Exception ex) {
|
||||
throw convertLettuceAccessException(ex);
|
||||
}
|
||||
return connection.invoke().from(RedisSetAsyncCommands::spop, key, count).get(ArrayList::new);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -331,19 +196,7 @@ class LettuceSetCommands implements RedisSetCommands {
|
||||
|
||||
Assert.notNull(key, "Key must not be null!");
|
||||
|
||||
try {
|
||||
if (isPipelined()) {
|
||||
pipeline(connection.newLettuceResult(getAsyncConnection().srandmember(key)));
|
||||
return null;
|
||||
}
|
||||
if (isQueueing()) {
|
||||
transaction(connection.newLettuceResult(getAsyncConnection().srandmember(key)));
|
||||
return null;
|
||||
}
|
||||
return getConnection().srandmember(key);
|
||||
} catch (Exception ex) {
|
||||
throw convertLettuceAccessException(ex);
|
||||
}
|
||||
return connection.invoke().just(RedisSetAsyncCommands::srandmember, key);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -355,19 +208,7 @@ class LettuceSetCommands implements RedisSetCommands {
|
||||
|
||||
Assert.notNull(key, "Key must not be null!");
|
||||
|
||||
try {
|
||||
if (isPipelined()) {
|
||||
pipeline(connection.newLettuceResult(getAsyncConnection().srandmember(key, count)));
|
||||
return null;
|
||||
}
|
||||
if (isQueueing()) {
|
||||
transaction(connection.newLettuceResult(getAsyncConnection().srandmember(key, count)));
|
||||
return null;
|
||||
}
|
||||
return LettuceConverters.toBytesList(getConnection().srandmember(key, count));
|
||||
} catch (Exception ex) {
|
||||
throw convertLettuceAccessException(ex);
|
||||
}
|
||||
return connection.invoke().just(RedisSetAsyncCommands::srandmember, key, count);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -381,19 +222,7 @@ class LettuceSetCommands implements RedisSetCommands {
|
||||
Assert.notNull(values, "Values must not be null!");
|
||||
Assert.noNullElements(values, "Values must not contain null elements!");
|
||||
|
||||
try {
|
||||
if (isPipelined()) {
|
||||
pipeline(connection.newLettuceResult(getAsyncConnection().srem(key, values)));
|
||||
return null;
|
||||
}
|
||||
if (isQueueing()) {
|
||||
transaction(connection.newLettuceResult(getAsyncConnection().srem(key, values)));
|
||||
return null;
|
||||
}
|
||||
return getConnection().srem(key, values);
|
||||
} catch (Exception ex) {
|
||||
throw convertLettuceAccessException(ex);
|
||||
}
|
||||
return connection.invoke().just(RedisSetAsyncCommands::srem, key, values);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -406,19 +235,7 @@ class LettuceSetCommands implements RedisSetCommands {
|
||||
Assert.notNull(keys, "Keys must not be null!");
|
||||
Assert.noNullElements(keys, "Keys must not contain null elements!");
|
||||
|
||||
try {
|
||||
if (isPipelined()) {
|
||||
pipeline(connection.newLettuceResult(getAsyncConnection().sunion(keys)));
|
||||
return null;
|
||||
}
|
||||
if (isQueueing()) {
|
||||
transaction(connection.newLettuceResult(getAsyncConnection().sunion(keys)));
|
||||
return null;
|
||||
}
|
||||
return getConnection().sunion(keys);
|
||||
} catch (Exception ex) {
|
||||
throw convertLettuceAccessException(ex);
|
||||
}
|
||||
return connection.invoke().just(RedisSetAsyncCommands::sunion, keys);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -432,19 +249,7 @@ class LettuceSetCommands implements RedisSetCommands {
|
||||
Assert.notNull(keys, "Source keys must not be null!");
|
||||
Assert.noNullElements(keys, "Source keys must not contain null elements!");
|
||||
|
||||
try {
|
||||
if (isPipelined()) {
|
||||
pipeline(connection.newLettuceResult(getAsyncConnection().sunionstore(destKey, keys)));
|
||||
return null;
|
||||
}
|
||||
if (isQueueing()) {
|
||||
transaction(connection.newLettuceResult(getAsyncConnection().sunionstore(destKey, keys)));
|
||||
return null;
|
||||
}
|
||||
return getConnection().sunionstore(destKey, keys);
|
||||
} catch (Exception ex) {
|
||||
throw convertLettuceAccessException(ex);
|
||||
}
|
||||
return connection.invoke().just(RedisSetAsyncCommands::sunionstore, destKey, keys);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -472,14 +277,15 @@ class LettuceSetCommands implements RedisSetCommands {
|
||||
@Override
|
||||
protected ScanIteration<byte[]> doScan(byte[] key, long cursorId, ScanOptions options) {
|
||||
|
||||
if (isQueueing() || isPipelined()) {
|
||||
if (connection.isQueueing() || connection.isPipelined()) {
|
||||
throw new UnsupportedOperationException("'SSCAN' cannot be called in pipeline / transaction mode.");
|
||||
}
|
||||
|
||||
io.lettuce.core.ScanCursor scanCursor = connection.getScanCursor(cursorId);
|
||||
ScanArgs scanArgs = LettuceConverters.toScanArgs(options);
|
||||
|
||||
ValueScanCursor<byte[]> valueScanCursor = getConnection().sscan(key, scanCursor, scanArgs);
|
||||
ValueScanCursor<byte[]> valueScanCursor = connection.invoke().just(RedisSetAsyncCommands::sscan, key,
|
||||
scanCursor, scanArgs);
|
||||
String nextCursorId = valueScanCursor.getCursor();
|
||||
|
||||
List<byte[]> values = connection.failsafeReadScanValues(valueScanCursor.getValues(), null);
|
||||
@@ -493,32 +299,8 @@ class LettuceSetCommands implements RedisSetCommands {
|
||||
}.open();
|
||||
}
|
||||
|
||||
private boolean isPipelined() {
|
||||
return connection.isPipelined();
|
||||
}
|
||||
|
||||
private boolean isQueueing() {
|
||||
return connection.isQueueing();
|
||||
}
|
||||
|
||||
private void pipeline(LettuceResult result) {
|
||||
connection.pipeline(result);
|
||||
}
|
||||
|
||||
private void transaction(LettuceResult result) {
|
||||
connection.transaction(result);
|
||||
}
|
||||
|
||||
RedisClusterAsyncCommands<byte[], byte[]> getAsyncConnection() {
|
||||
return connection.getAsyncConnection();
|
||||
}
|
||||
|
||||
public RedisClusterCommands<byte[], byte[]> getConnection() {
|
||||
public RedisClusterCommands<byte[], byte[]> getCommands() {
|
||||
return connection.getConnection();
|
||||
}
|
||||
|
||||
private DataAccessException convertLettuceAccessException(Exception ex) {
|
||||
return connection.convertLettuceAccessException(ex);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -19,15 +19,14 @@ import io.lettuce.core.XAddArgs;
|
||||
import io.lettuce.core.XClaimArgs;
|
||||
import io.lettuce.core.XGroupCreateArgs;
|
||||
import io.lettuce.core.XReadArgs;
|
||||
import io.lettuce.core.api.async.RedisStreamAsyncCommands;
|
||||
import io.lettuce.core.cluster.api.async.RedisClusterAsyncCommands;
|
||||
import io.lettuce.core.cluster.api.sync.RedisClusterCommands;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
import java.util.function.Function;
|
||||
|
||||
import org.springframework.dao.DataAccessException;
|
||||
import org.springframework.data.domain.Range;
|
||||
import org.springframework.data.redis.connection.RedisStreamCommands;
|
||||
import org.springframework.data.redis.connection.RedisZSetCommands.Limit;
|
||||
@@ -73,19 +72,7 @@ class LettuceStreamCommands implements RedisStreamCommands {
|
||||
|
||||
String[] ids = entryIdsToString(recordIds);
|
||||
|
||||
try {
|
||||
if (isPipelined()) {
|
||||
pipeline(connection.newLettuceResult(getAsyncConnection().xack(key, LettuceConverters.toBytes(group), ids)));
|
||||
return null;
|
||||
}
|
||||
if (isQueueing()) {
|
||||
transaction(connection.newLettuceResult(getAsyncConnection().xack(key, LettuceConverters.toBytes(group), ids)));
|
||||
return null;
|
||||
}
|
||||
return getConnection().xack(key, LettuceConverters.toBytes(group), ids);
|
||||
} catch (Exception ex) {
|
||||
throw convertLettuceAccessException(ex);
|
||||
}
|
||||
return connection.invoke().just(RedisStreamAsyncCommands::xack, key, LettuceConverters.toBytes(group), ids);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -104,25 +91,8 @@ class LettuceStreamCommands implements RedisStreamCommands {
|
||||
args.maxlen(options.getMaxlen());
|
||||
}
|
||||
|
||||
try {
|
||||
if (isPipelined()) {
|
||||
|
||||
pipeline(connection.newLettuceResult(getAsyncConnection().xadd(record.getStream(), args, record.getValue()),
|
||||
RecordId::of));
|
||||
return null;
|
||||
}
|
||||
if (isQueueing()) {
|
||||
|
||||
transaction(connection.newLettuceResult(getAsyncConnection().xadd(record.getStream(), args, record.getValue()),
|
||||
RecordId::of));
|
||||
return null;
|
||||
}
|
||||
|
||||
return RecordId.of(getConnection().xadd(record.getStream(), args, record.getValue()));
|
||||
|
||||
} catch (Exception ex) {
|
||||
throw convertLettuceAccessException(ex);
|
||||
}
|
||||
return connection.invoke().from(RedisStreamAsyncCommands::xadd, record.getStream(), args, record.getValue())
|
||||
.get(RecordId::of);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -137,25 +107,8 @@ class LettuceStreamCommands implements RedisStreamCommands {
|
||||
LettuceConverters.toBytes(newOwner));
|
||||
XClaimArgs args = StreamConverters.toXClaimArgs(options).justid();
|
||||
|
||||
try {
|
||||
if (isPipelined()) {
|
||||
|
||||
pipeline(connection.newLettuceResult(getAsyncConnection().xclaim(key, from, args, ids),
|
||||
StreamConverters.messagesToIds()));
|
||||
return null;
|
||||
}
|
||||
if (isQueueing()) {
|
||||
|
||||
transaction(connection.newLettuceResult(getAsyncConnection().xclaim(key, from, args, ids),
|
||||
StreamConverters.messagesToIds()));
|
||||
return null;
|
||||
}
|
||||
|
||||
} catch (Exception ex) {
|
||||
throw convertLettuceAccessException(ex);
|
||||
}
|
||||
|
||||
return StreamConverters.messagesToIds().convert(getConnection().xclaim(key, from, args, ids));
|
||||
return connection.invoke().fromMany(RedisStreamAsyncCommands::xclaim, key, from, args, ids)
|
||||
.toList(it -> RecordId.of(it.getId()));
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -170,21 +123,8 @@ class LettuceStreamCommands implements RedisStreamCommands {
|
||||
LettuceConverters.toBytes(newOwner));
|
||||
XClaimArgs args = StreamConverters.toXClaimArgs(options);
|
||||
|
||||
try {
|
||||
if (isPipelined()) {
|
||||
pipeline(connection.newLettuceResult(getAsyncConnection().xclaim(key, from, args, ids),
|
||||
StreamConverters.byteRecordListConverter()));
|
||||
return null;
|
||||
}
|
||||
if (isQueueing()) {
|
||||
transaction(connection.newLettuceResult(getAsyncConnection().xclaim(key, from, args, ids),
|
||||
StreamConverters.byteRecordListConverter()));
|
||||
return null;
|
||||
}
|
||||
return StreamConverters.byteRecordListConverter().convert(getConnection().xclaim(key, from, args, ids));
|
||||
} catch (Exception ex) {
|
||||
throw convertLettuceAccessException(ex);
|
||||
}
|
||||
return connection.invoke().fromMany(RedisStreamAsyncCommands::xclaim, key, from, args, ids)
|
||||
.toList(StreamConverters.byteRecordConverter());
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -197,19 +137,7 @@ class LettuceStreamCommands implements RedisStreamCommands {
|
||||
Assert.notNull(key, "Key must not be null!");
|
||||
Assert.notNull(recordIds, "recordIds must not be null!");
|
||||
|
||||
try {
|
||||
if (isPipelined()) {
|
||||
pipeline(connection.newLettuceResult(getAsyncConnection().xdel(key, entryIdsToString(recordIds))));
|
||||
return null;
|
||||
}
|
||||
if (isQueueing()) {
|
||||
transaction(connection.newLettuceResult(getAsyncConnection().xdel(key, entryIdsToString(recordIds))));
|
||||
return null;
|
||||
}
|
||||
return getConnection().xdel(key, entryIdsToString(recordIds));
|
||||
} catch (Exception ex) {
|
||||
throw convertLettuceAccessException(ex);
|
||||
}
|
||||
return connection.invoke().just(RedisStreamAsyncCommands::xdel, key, entryIdsToString(recordIds));
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -232,24 +160,10 @@ class LettuceStreamCommands implements RedisStreamCommands {
|
||||
Assert.hasText(groupName, "Group name must not be null or empty!");
|
||||
Assert.notNull(readOffset, "ReadOffset must not be null!");
|
||||
|
||||
try {
|
||||
XReadArgs.StreamOffset<byte[]> streamOffset = XReadArgs.StreamOffset.from(key, readOffset.getOffset());
|
||||
XReadArgs.StreamOffset<byte[]> streamOffset = XReadArgs.StreamOffset.from(key, readOffset.getOffset());
|
||||
|
||||
if (isPipelined()) {
|
||||
pipeline(connection.newLettuceResult(getAsyncConnection().xgroupCreate(streamOffset,
|
||||
LettuceConverters.toBytes(groupName), XGroupCreateArgs.Builder.mkstream(mkSteam))));
|
||||
return null;
|
||||
}
|
||||
if (isQueueing()) {
|
||||
transaction(connection.newLettuceResult(getAsyncConnection().xgroupCreate(streamOffset,
|
||||
LettuceConverters.toBytes(groupName), XGroupCreateArgs.Builder.mkstream(mkSteam))));
|
||||
return null;
|
||||
}
|
||||
return getConnection().xgroupCreate(streamOffset, LettuceConverters.toBytes(groupName),
|
||||
XGroupCreateArgs.Builder.mkstream(mkSteam));
|
||||
} catch (Exception ex) {
|
||||
throw convertLettuceAccessException(ex);
|
||||
}
|
||||
return connection.invoke().just(RedisStreamAsyncCommands::xgroupCreate, streamOffset,
|
||||
LettuceConverters.toBytes(groupName), XGroupCreateArgs.Builder.mkstream(mkSteam));
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -262,23 +176,10 @@ class LettuceStreamCommands implements RedisStreamCommands {
|
||||
Assert.notNull(key, "Key must not be null!");
|
||||
Assert.notNull(consumer, "Consumer must not be null!");
|
||||
|
||||
try {
|
||||
io.lettuce.core.Consumer<byte[]> lettuceConsumer = toConsumer(consumer);
|
||||
io.lettuce.core.Consumer<byte[]> lettuceConsumer = toConsumer(consumer);
|
||||
|
||||
if (isPipelined()) {
|
||||
pipeline(connection.newLettuceResult(getAsyncConnection().xgroupDelconsumer(key, lettuceConsumer),
|
||||
Objects::nonNull));
|
||||
return null;
|
||||
}
|
||||
if (isQueueing()) {
|
||||
transaction(connection.newLettuceResult(getAsyncConnection().xgroupDelconsumer(key, lettuceConsumer),
|
||||
Objects::nonNull));
|
||||
return null;
|
||||
}
|
||||
return Objects.nonNull(getConnection().xgroupDelconsumer(key, lettuceConsumer));
|
||||
} catch (Exception ex) {
|
||||
throw convertLettuceAccessException(ex);
|
||||
}
|
||||
return connection.invoke().from(RedisStreamAsyncCommands::xgroupDelconsumer, key, lettuceConsumer)
|
||||
.get(Objects::nonNull);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -291,21 +192,7 @@ class LettuceStreamCommands implements RedisStreamCommands {
|
||||
Assert.notNull(key, "Key must not be null!");
|
||||
Assert.hasText(groupName, "Group name must not be null or empty!");
|
||||
|
||||
try {
|
||||
if (isPipelined()) {
|
||||
pipeline(
|
||||
connection.newLettuceResult(getAsyncConnection().xgroupDestroy(key, LettuceConverters.toBytes(groupName))));
|
||||
return null;
|
||||
}
|
||||
if (isQueueing()) {
|
||||
transaction(
|
||||
connection.newLettuceResult(getAsyncConnection().xgroupDestroy(key, LettuceConverters.toBytes(groupName))));
|
||||
return null;
|
||||
}
|
||||
return getConnection().xgroupDestroy(key, LettuceConverters.toBytes(groupName));
|
||||
} catch (Exception ex) {
|
||||
throw convertLettuceAccessException(ex);
|
||||
}
|
||||
return connection.invoke().just(RedisStreamAsyncCommands::xgroupDestroy, key, LettuceConverters.toBytes(groupName));
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -317,19 +204,7 @@ class LettuceStreamCommands implements RedisStreamCommands {
|
||||
|
||||
Assert.notNull(key, "Key must not be null!");
|
||||
|
||||
try {
|
||||
if (isPipelined()) {
|
||||
pipeline(connection.newLettuceResult(getAsyncConnection().xinfoStream(key), XInfoStream::fromList));
|
||||
return null;
|
||||
}
|
||||
if (isQueueing()) {
|
||||
transaction(connection.newLettuceResult(getAsyncConnection().xinfoStream(key), XInfoStream::fromList));
|
||||
return null;
|
||||
}
|
||||
return XInfoStream.fromList(getConnection().xinfoStream(key));
|
||||
} catch (Exception ex) {
|
||||
throw convertLettuceAccessException(ex);
|
||||
}
|
||||
return connection.invoke().from(RedisStreamAsyncCommands::xinfoStream, key).get(XInfoStream::fromList);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -341,19 +216,7 @@ class LettuceStreamCommands implements RedisStreamCommands {
|
||||
|
||||
Assert.notNull(key, "Key must not be null!");
|
||||
|
||||
try {
|
||||
if (isPipelined()) {
|
||||
pipeline(connection.newLettuceResult(getAsyncConnection().xinfoGroups(key), XInfoGroups::fromList));
|
||||
return null;
|
||||
}
|
||||
if (isQueueing()) {
|
||||
transaction(connection.newLettuceResult(getAsyncConnection().xinfoGroups(key), XInfoGroups::fromList));
|
||||
return null;
|
||||
}
|
||||
return XInfoGroups.fromList(getConnection().xinfoGroups(key));
|
||||
} catch (Exception ex) {
|
||||
throw convertLettuceAccessException(ex);
|
||||
}
|
||||
return connection.invoke().from(RedisStreamAsyncCommands::xinfoGroups, key).get(XInfoGroups::fromList);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -366,23 +229,8 @@ class LettuceStreamCommands implements RedisStreamCommands {
|
||||
Assert.notNull(key, "Key must not be null!");
|
||||
Assert.notNull(groupName, "GroupName must not be null!");
|
||||
|
||||
byte[] binaryGroupName = LettuceConverters.toBytes(groupName);
|
||||
|
||||
try {
|
||||
if (isPipelined()) {
|
||||
pipeline(connection.newLettuceResult(getAsyncConnection().xinfoConsumers(key, binaryGroupName),
|
||||
it -> XInfoConsumers.fromList(groupName, it)));
|
||||
return null;
|
||||
}
|
||||
if (isQueueing()) {
|
||||
transaction(connection.newLettuceResult(getAsyncConnection().xinfoConsumers(key, binaryGroupName),
|
||||
it -> XInfoConsumers.fromList(groupName, it)));
|
||||
return null;
|
||||
}
|
||||
return XInfoConsumers.fromList(groupName, getConnection().xinfoConsumers(key, binaryGroupName));
|
||||
} catch (Exception ex) {
|
||||
throw convertLettuceAccessException(ex);
|
||||
}
|
||||
return connection.invoke().from(RedisStreamAsyncCommands::xinfoConsumers, key, LettuceConverters.toBytes(groupName))
|
||||
.get(it -> XInfoConsumers.fromList(groupName, it));
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -394,19 +242,7 @@ class LettuceStreamCommands implements RedisStreamCommands {
|
||||
|
||||
Assert.notNull(key, "Key must not be null!");
|
||||
|
||||
try {
|
||||
if (isPipelined()) {
|
||||
pipeline(connection.newLettuceResult(getAsyncConnection().xlen(key)));
|
||||
return null;
|
||||
}
|
||||
if (isQueueing()) {
|
||||
transaction(connection.newLettuceResult(getAsyncConnection().xlen(key)));
|
||||
return null;
|
||||
}
|
||||
return getConnection().xlen(key);
|
||||
} catch (Exception ex) {
|
||||
throw convertLettuceAccessException(ex);
|
||||
}
|
||||
return connection.invoke().just(RedisStreamAsyncCommands::xlen, key);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -417,21 +253,9 @@ class LettuceStreamCommands implements RedisStreamCommands {
|
||||
public PendingMessagesSummary xPending(byte[] key, String groupName) {
|
||||
|
||||
byte[] group = LettuceConverters.toBytes(groupName);
|
||||
try {
|
||||
if (isPipelined()) {
|
||||
pipeline(connection.newLettuceResult(getAsyncConnection().xpending(key, group),
|
||||
it -> StreamConverters.toPendingMessagesInfo(groupName, it)));
|
||||
return null;
|
||||
}
|
||||
if (isQueueing()) {
|
||||
transaction(connection.newLettuceResult(getAsyncConnection().xpending(key, group),
|
||||
it -> StreamConverters.toPendingMessagesInfo(groupName, it)));
|
||||
return null;
|
||||
}
|
||||
return StreamConverters.toPendingMessagesInfo(groupName, getConnection().xpending(key, group));
|
||||
} catch (Exception ex) {
|
||||
throw convertLettuceAccessException(ex);
|
||||
}
|
||||
|
||||
return connection.invoke().from(RedisStreamAsyncCommands::xpending, key, group)
|
||||
.get(it -> StreamConverters.toPendingMessagesInfo(groupName, it));
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -442,46 +266,21 @@ class LettuceStreamCommands implements RedisStreamCommands {
|
||||
public PendingMessages xPending(byte[] key, String groupName, XPendingOptions options) {
|
||||
|
||||
byte[] group = LettuceConverters.toBytes(groupName);
|
||||
io.lettuce.core.Range<String> range = RangeConverter.toRangeWithDefault(options.getRange(), "-", "+", Function.identity());
|
||||
io.lettuce.core.Range<String> range = RangeConverter.toRangeWithDefault(options.getRange(), "-", "+",
|
||||
Function.identity());
|
||||
io.lettuce.core.Limit limit = options.isLimited() ? io.lettuce.core.Limit.from(options.getCount())
|
||||
: io.lettuce.core.Limit.unlimited();
|
||||
|
||||
try {
|
||||
if (options.hasConsumer()) {
|
||||
if (options.hasConsumer()) {
|
||||
|
||||
if (isPipelined()) {
|
||||
pipeline(connection.newLettuceResult(getAsyncConnection().xpending(key,
|
||||
io.lettuce.core.Consumer.from(group, LettuceConverters.toBytes(options.getConsumerName())), range, limit),
|
||||
it -> StreamConverters.toPendingMessages(groupName, options.getRange(), it)));
|
||||
return null;
|
||||
}
|
||||
if (isQueueing()) {
|
||||
transaction(connection.newLettuceResult(getAsyncConnection().xpending(key,
|
||||
io.lettuce.core.Consumer.from(group, LettuceConverters.toBytes(options.getConsumerName())), range, limit),
|
||||
it -> StreamConverters.toPendingMessages(groupName, options.getRange(), it)));
|
||||
return null;
|
||||
}
|
||||
return StreamConverters.toPendingMessages(groupName, options.getRange(), getConnection().xpending(key,
|
||||
io.lettuce.core.Consumer.from(group, LettuceConverters.toBytes(options.getConsumerName())), range, limit));
|
||||
|
||||
} else {
|
||||
|
||||
if (isPipelined()) {
|
||||
pipeline(connection.newLettuceResult(getAsyncConnection().xpending(key, group, range, limit),
|
||||
it -> StreamConverters.toPendingMessages(groupName, options.getRange(), it)));
|
||||
return null;
|
||||
}
|
||||
if (isQueueing()) {
|
||||
transaction(connection.newLettuceResult(getAsyncConnection().xpending(key, group, range, limit),
|
||||
it -> StreamConverters.toPendingMessages(groupName, options.getRange(), it)));
|
||||
return null;
|
||||
}
|
||||
return StreamConverters.toPendingMessages(groupName, options.getRange(),
|
||||
getConnection().xpending(key, group, range, limit));
|
||||
}
|
||||
} catch (Exception ex) {
|
||||
throw convertLettuceAccessException(ex);
|
||||
return connection.invoke()
|
||||
.from(RedisStreamAsyncCommands::xpending, key,
|
||||
io.lettuce.core.Consumer.from(group, LettuceConverters.toBytes(options.getConsumerName())), range, limit)
|
||||
.get(it -> StreamConverters.toPendingMessages(groupName, options.getRange(), it));
|
||||
}
|
||||
|
||||
return connection.invoke().from(RedisStreamAsyncCommands::xpending, key, group, range, limit)
|
||||
.get(it -> StreamConverters.toPendingMessages(groupName, options.getRange(), it));
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -497,24 +296,9 @@ class LettuceStreamCommands implements RedisStreamCommands {
|
||||
|
||||
io.lettuce.core.Range<String> lettuceRange = RangeConverter.toRange(range, Function.identity());
|
||||
io.lettuce.core.Limit lettuceLimit = LettuceConverters.toLimit(limit);
|
||||
try {
|
||||
if (isPipelined()) {
|
||||
pipeline(connection.newLettuceResult(getAsyncConnection().xrange(key, lettuceRange, lettuceLimit),
|
||||
StreamConverters.byteRecordListConverter()));
|
||||
return null;
|
||||
}
|
||||
if (isQueueing()) {
|
||||
transaction(connection.newLettuceResult(getAsyncConnection().xrange(key, lettuceRange, lettuceLimit),
|
||||
StreamConverters.byteRecordListConverter()));
|
||||
return null;
|
||||
}
|
||||
|
||||
return StreamConverters.byteRecordListConverter()
|
||||
.convert(getConnection().xrange(key, lettuceRange, lettuceLimit));
|
||||
|
||||
} catch (Exception ex) {
|
||||
throw convertLettuceAccessException(ex);
|
||||
}
|
||||
return connection.invoke().fromMany(RedisStreamAsyncCommands::xrange, key, lettuceRange, lettuceLimit)
|
||||
.toList(StreamConverters.byteRecordConverter());
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -532,38 +316,13 @@ class LettuceStreamCommands implements RedisStreamCommands {
|
||||
|
||||
if (readOptions.isBlocking()) {
|
||||
|
||||
try {
|
||||
if (isPipelined()) {
|
||||
pipeline(connection.newLettuceResult(getAsyncDedicatedConnection().xread(args, streamOffsets),
|
||||
StreamConverters.byteRecordListConverter()));
|
||||
return null;
|
||||
}
|
||||
if (isQueueing()) {
|
||||
transaction(connection.newLettuceResult(getAsyncDedicatedConnection().xread(args, streamOffsets),
|
||||
StreamConverters.byteRecordListConverter()));
|
||||
return null;
|
||||
}
|
||||
return StreamConverters.byteRecordListConverter().convert(getDedicatedConnection().xread(args, streamOffsets));
|
||||
} catch (Exception ex) {
|
||||
throw convertLettuceAccessException(ex);
|
||||
}
|
||||
return connection.invoke(getAsyncDedicatedConnection())
|
||||
.fromMany(RedisStreamAsyncCommands::xread, args, streamOffsets)
|
||||
.toList(StreamConverters.byteRecordConverter());
|
||||
}
|
||||
|
||||
try {
|
||||
if (isPipelined()) {
|
||||
pipeline(connection.newLettuceResult(getAsyncConnection().xread(args, streamOffsets),
|
||||
StreamConverters.byteRecordListConverter()));
|
||||
return null;
|
||||
}
|
||||
if (isQueueing()) {
|
||||
transaction(connection.newLettuceResult(getAsyncConnection().xread(args, streamOffsets),
|
||||
StreamConverters.byteRecordListConverter()));
|
||||
return null;
|
||||
}
|
||||
return StreamConverters.byteRecordListConverter().convert(getConnection().xread(args, streamOffsets));
|
||||
} catch (Exception ex) {
|
||||
throw convertLettuceAccessException(ex);
|
||||
}
|
||||
return connection.invoke().fromMany(RedisStreamAsyncCommands::xread, args, streamOffsets)
|
||||
.toList(StreamConverters.byteRecordConverter());
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -584,42 +343,13 @@ class LettuceStreamCommands implements RedisStreamCommands {
|
||||
|
||||
if (readOptions.isBlocking()) {
|
||||
|
||||
try {
|
||||
if (isPipelined()) {
|
||||
pipeline(connection.newLettuceResult(
|
||||
getAsyncDedicatedConnection().xreadgroup(lettuceConsumer, args, streamOffsets),
|
||||
StreamConverters.byteRecordListConverter()));
|
||||
return null;
|
||||
}
|
||||
if (isQueueing()) {
|
||||
transaction(connection.newLettuceResult(
|
||||
getAsyncDedicatedConnection().xreadgroup(lettuceConsumer, args, streamOffsets),
|
||||
StreamConverters.byteRecordListConverter()));
|
||||
return null;
|
||||
}
|
||||
return StreamConverters.byteRecordListConverter()
|
||||
.convert(getDedicatedConnection().xreadgroup(lettuceConsumer, args, streamOffsets));
|
||||
} catch (Exception ex) {
|
||||
throw convertLettuceAccessException(ex);
|
||||
}
|
||||
return connection.invoke(getAsyncDedicatedConnection())
|
||||
.fromMany(RedisStreamAsyncCommands::xreadgroup, lettuceConsumer, args, streamOffsets)
|
||||
.toList(StreamConverters.byteRecordConverter());
|
||||
}
|
||||
|
||||
try {
|
||||
if (isPipelined()) {
|
||||
pipeline(connection.newLettuceResult(getAsyncConnection().xreadgroup(lettuceConsumer, args, streamOffsets),
|
||||
StreamConverters.byteRecordListConverter()));
|
||||
return null;
|
||||
}
|
||||
if (isQueueing()) {
|
||||
transaction(connection.newLettuceResult(getAsyncConnection().xreadgroup(lettuceConsumer, args, streamOffsets),
|
||||
StreamConverters.byteRecordListConverter()));
|
||||
return null;
|
||||
}
|
||||
return StreamConverters.byteRecordListConverter()
|
||||
.convert(getConnection().xreadgroup(lettuceConsumer, args, streamOffsets));
|
||||
} catch (Exception ex) {
|
||||
throw convertLettuceAccessException(ex);
|
||||
}
|
||||
return connection.invoke().fromMany(RedisStreamAsyncCommands::xreadgroup, lettuceConsumer, args, streamOffsets)
|
||||
.toList(StreamConverters.byteRecordConverter());
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -635,22 +365,10 @@ class LettuceStreamCommands implements RedisStreamCommands {
|
||||
|
||||
io.lettuce.core.Range<String> lettuceRange = RangeConverter.toRange(range, Function.identity());
|
||||
io.lettuce.core.Limit lettuceLimit = LettuceConverters.toLimit(limit);
|
||||
try {
|
||||
if (isPipelined()) {
|
||||
pipeline(connection.newLettuceResult(getAsyncConnection().xrevrange(key, lettuceRange, lettuceLimit),
|
||||
StreamConverters.byteRecordListConverter()));
|
||||
return null;
|
||||
}
|
||||
if (isQueueing()) {
|
||||
transaction(connection.newLettuceResult(getAsyncConnection().xrevrange(key, lettuceRange, lettuceLimit),
|
||||
StreamConverters.byteRecordListConverter()));
|
||||
return null;
|
||||
}
|
||||
return StreamConverters.byteRecordListConverter()
|
||||
.convert(getConnection().xrevrange(key, lettuceRange, lettuceLimit));
|
||||
} catch (Exception ex) {
|
||||
throw convertLettuceAccessException(ex);
|
||||
}
|
||||
|
||||
return connection.invoke(getAsyncDedicatedConnection())
|
||||
.fromMany(RedisStreamAsyncCommands::xrevrange, key, lettuceRange, lettuceLimit)
|
||||
.toList(StreamConverters.byteRecordConverter());
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -670,57 +388,13 @@ class LettuceStreamCommands implements RedisStreamCommands {
|
||||
public Long xTrim(byte[] key, long count, boolean approximateTrimming) {
|
||||
Assert.notNull(key, "Key must not be null!");
|
||||
|
||||
try {
|
||||
if (isPipelined()) {
|
||||
pipeline(connection.newLettuceResult(getAsyncConnection().xtrim(key, approximateTrimming, count)));
|
||||
return null;
|
||||
}
|
||||
if (isQueueing()) {
|
||||
transaction(connection.newLettuceResult(getAsyncConnection().xtrim(key, approximateTrimming, count)));
|
||||
return null;
|
||||
}
|
||||
return getConnection().xtrim(key, approximateTrimming, count);
|
||||
} catch (Exception ex) {
|
||||
throw convertLettuceAccessException(ex);
|
||||
}
|
||||
}
|
||||
|
||||
private boolean isPipelined() {
|
||||
return connection.isPipelined();
|
||||
}
|
||||
|
||||
private boolean isQueueing() {
|
||||
return connection.isQueueing();
|
||||
}
|
||||
|
||||
private void pipeline(LettuceResult result) {
|
||||
connection.pipeline(result);
|
||||
}
|
||||
|
||||
private void transaction(LettuceResult result) {
|
||||
connection.transaction(result);
|
||||
}
|
||||
|
||||
RedisClusterAsyncCommands<byte[], byte[]> getAsyncConnection() {
|
||||
return connection.getAsyncConnection();
|
||||
}
|
||||
|
||||
RedisClusterCommands<byte[], byte[]> getConnection() {
|
||||
return connection.getConnection();
|
||||
return connection.invoke().just(RedisStreamAsyncCommands::xtrim, key, approximateTrimming, count);
|
||||
}
|
||||
|
||||
RedisClusterAsyncCommands<byte[], byte[]> getAsyncDedicatedConnection() {
|
||||
return connection.getAsyncDedicatedConnection();
|
||||
}
|
||||
|
||||
RedisClusterCommands<byte[], byte[]> getDedicatedConnection() {
|
||||
return connection.getDedicatedConnection();
|
||||
}
|
||||
|
||||
private DataAccessException convertLettuceAccessException(Exception ex) {
|
||||
return connection.convertLettuceAccessException(ex);
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private static XReadArgs.StreamOffset<byte[]>[] toStreamOffsets(StreamOffset<byte[]>[] streams) {
|
||||
|
||||
|
||||
@@ -16,15 +16,11 @@
|
||||
package org.springframework.data.redis.connection.lettuce;
|
||||
|
||||
import io.lettuce.core.BitFieldArgs;
|
||||
import io.lettuce.core.RedisFuture;
|
||||
import io.lettuce.core.cluster.api.async.RedisClusterAsyncCommands;
|
||||
import io.lettuce.core.cluster.api.sync.RedisClusterCommands;
|
||||
import io.lettuce.core.api.async.RedisStringAsyncCommands;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.Future;
|
||||
|
||||
import org.springframework.dao.DataAccessException;
|
||||
import org.springframework.data.domain.Range;
|
||||
import org.springframework.data.redis.connection.BitFieldSubCommands;
|
||||
import org.springframework.data.redis.connection.RedisStringCommands;
|
||||
@@ -56,19 +52,7 @@ class LettuceStringCommands implements RedisStringCommands {
|
||||
|
||||
Assert.notNull(key, "Key must not be null!");
|
||||
|
||||
try {
|
||||
if (isPipelined()) {
|
||||
pipeline(connection.newLettuceResult(getAsyncConnection().get(key)));
|
||||
return null;
|
||||
}
|
||||
if (isQueueing()) {
|
||||
transaction(connection.newLettuceResult(getAsyncConnection().get(key)));
|
||||
return null;
|
||||
}
|
||||
return getConnection().get(key);
|
||||
} catch (Exception ex) {
|
||||
throw convertLettuceAccessException(ex);
|
||||
}
|
||||
return connection.invoke().just(RedisStringAsyncCommands::get, key);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -81,19 +65,7 @@ class LettuceStringCommands implements RedisStringCommands {
|
||||
Assert.notNull(key, "Key must not be null!");
|
||||
Assert.notNull(value, "Value must not be null!");
|
||||
|
||||
try {
|
||||
if (isPipelined()) {
|
||||
pipeline(connection.newLettuceResult(getAsyncConnection().getset(key, value)));
|
||||
return null;
|
||||
}
|
||||
if (isQueueing()) {
|
||||
transaction(connection.newLettuceResult(getAsyncConnection().getset(key, value)));
|
||||
return null;
|
||||
}
|
||||
return getConnection().getset(key, value);
|
||||
} catch (Exception ex) {
|
||||
throw convertLettuceAccessException(ex);
|
||||
}
|
||||
return connection.invoke().just(RedisStringAsyncCommands::getset, key, value);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -106,22 +78,8 @@ class LettuceStringCommands implements RedisStringCommands {
|
||||
Assert.notNull(keys, "Keys must not be null!");
|
||||
Assert.noNullElements(keys, "Keys must not contain null elements!");
|
||||
|
||||
try {
|
||||
if (isPipelined()) {
|
||||
pipeline(
|
||||
connection.newLettuceResult(getAsyncConnection().mget(keys), LettuceConverters.keyValueListUnwrapper()));
|
||||
return null;
|
||||
}
|
||||
if (isQueueing()) {
|
||||
transaction(
|
||||
connection.newLettuceResult(getAsyncConnection().mget(keys), LettuceConverters.keyValueListUnwrapper()));
|
||||
return null;
|
||||
}
|
||||
|
||||
return LettuceConverters.<byte[], byte[]> keyValueListUnwrapper().convert(getConnection().mget(keys));
|
||||
} catch (Exception ex) {
|
||||
throw convertLettuceAccessException(ex);
|
||||
}
|
||||
return connection.invoke().fromMany(RedisStringAsyncCommands::mget, keys)
|
||||
.toList(source -> source.getValueOrElse(null));
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -134,21 +92,8 @@ class LettuceStringCommands implements RedisStringCommands {
|
||||
Assert.notNull(key, "Key must not be null!");
|
||||
Assert.notNull(value, "Value must not be null!");
|
||||
|
||||
try {
|
||||
if (isPipelined()) {
|
||||
pipeline(
|
||||
connection.newLettuceResult(getAsyncConnection().set(key, value), Converters.stringToBooleanConverter()));
|
||||
return null;
|
||||
}
|
||||
if (isQueueing()) {
|
||||
transaction(
|
||||
connection.newLettuceResult(getAsyncConnection().set(key, value), Converters.stringToBooleanConverter()));
|
||||
return null;
|
||||
}
|
||||
return Converters.stringToBoolean(getConnection().set(key, value));
|
||||
} catch (Exception ex) {
|
||||
throw convertLettuceAccessException(ex);
|
||||
}
|
||||
return connection.invoke().from(RedisStringAsyncCommands::set, key, value)
|
||||
.get(Converters.stringToBooleanConverter());
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -163,24 +108,9 @@ class LettuceStringCommands implements RedisStringCommands {
|
||||
Assert.notNull(expiration, "Expiration must not be null!");
|
||||
Assert.notNull(option, "Option must not be null!");
|
||||
|
||||
try {
|
||||
if (isPipelined()) {
|
||||
pipeline(connection.newLettuceResult(
|
||||
getAsyncConnection().set(key, value, LettuceConverters.toSetArgs(expiration, option)),
|
||||
Converters.stringToBooleanConverter(), () -> false));
|
||||
return null;
|
||||
}
|
||||
if (isQueueing()) {
|
||||
transaction(connection.newLettuceResult(
|
||||
getAsyncConnection().set(key, value, LettuceConverters.toSetArgs(expiration, option)),
|
||||
Converters.stringToBooleanConverter(), () -> false));
|
||||
return null;
|
||||
}
|
||||
return Converters
|
||||
.stringToBoolean(getConnection().set(key, value, LettuceConverters.toSetArgs(expiration, option)));
|
||||
} catch (Exception ex) {
|
||||
throw convertLettuceAccessException(ex);
|
||||
}
|
||||
return connection.invoke()
|
||||
.from(RedisStringAsyncCommands::set, key, value, LettuceConverters.toSetArgs(expiration, option))
|
||||
.getOrElse(LettuceConverters.stringToBooleanConverter(), () -> false);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -193,19 +123,7 @@ class LettuceStringCommands implements RedisStringCommands {
|
||||
Assert.notNull(key, "Key must not be null!");
|
||||
Assert.notNull(value, "Value must not be null!");
|
||||
|
||||
try {
|
||||
if (isPipelined()) {
|
||||
pipeline(connection.newLettuceResult(getAsyncConnection().setnx(key, value)));
|
||||
return null;
|
||||
}
|
||||
if (isQueueing()) {
|
||||
transaction(connection.newLettuceResult(getAsyncConnection().setnx(key, value)));
|
||||
return null;
|
||||
}
|
||||
return getConnection().setnx(key, value);
|
||||
} catch (Exception ex) {
|
||||
throw convertLettuceAccessException(ex);
|
||||
}
|
||||
return connection.invoke().just(RedisStringAsyncCommands::setnx, key, value);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -218,21 +136,8 @@ class LettuceStringCommands implements RedisStringCommands {
|
||||
Assert.notNull(key, "Key must not be null!");
|
||||
Assert.notNull(value, "Value must not be null!");
|
||||
|
||||
try {
|
||||
if (isPipelined()) {
|
||||
pipeline(connection.newLettuceResult(getAsyncConnection().setex(key, seconds, value),
|
||||
Converters.stringToBooleanConverter()));
|
||||
return null;
|
||||
}
|
||||
if (isQueueing()) {
|
||||
transaction(connection.newLettuceResult(getAsyncConnection().setex(key, seconds, value),
|
||||
Converters.stringToBooleanConverter()));
|
||||
return null;
|
||||
}
|
||||
return Converters.stringToBoolean(getConnection().setex(key, seconds, value));
|
||||
} catch (Exception ex) {
|
||||
throw convertLettuceAccessException(ex);
|
||||
}
|
||||
return connection.invoke().from(RedisStringAsyncCommands::setex, key, seconds, value)
|
||||
.get(Converters.stringToBooleanConverter());
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -245,21 +150,8 @@ class LettuceStringCommands implements RedisStringCommands {
|
||||
Assert.notNull(key, "Key must not be null!");
|
||||
Assert.notNull(value, "Value must not be null!");
|
||||
|
||||
try {
|
||||
if (isPipelined()) {
|
||||
pipeline(connection.newLettuceResult(getAsyncConnection().psetex(key, milliseconds, value),
|
||||
Converters.stringToBooleanConverter()));
|
||||
return null;
|
||||
}
|
||||
if (isQueueing()) {
|
||||
transaction(connection.newLettuceResult(getAsyncConnection().psetex(key, milliseconds, value),
|
||||
Converters.stringToBooleanConverter()));
|
||||
return null;
|
||||
}
|
||||
return Converters.stringToBoolean(getConnection().psetex(key, milliseconds, value));
|
||||
} catch (Exception ex) {
|
||||
throw convertLettuceAccessException(ex);
|
||||
}
|
||||
return connection.invoke().from(RedisStringAsyncCommands::psetex, key, milliseconds, value)
|
||||
.get(Converters.stringToBooleanConverter());
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -271,20 +163,7 @@ class LettuceStringCommands implements RedisStringCommands {
|
||||
|
||||
Assert.notNull(tuples, "Tuples must not be null!");
|
||||
|
||||
try {
|
||||
if (isPipelined()) {
|
||||
pipeline(connection.newLettuceResult(getAsyncConnection().mset(tuples), Converters.stringToBooleanConverter()));
|
||||
return null;
|
||||
}
|
||||
if (isQueueing()) {
|
||||
transaction(
|
||||
connection.newLettuceResult(getAsyncConnection().mset(tuples), Converters.stringToBooleanConverter()));
|
||||
return null;
|
||||
}
|
||||
return Converters.stringToBoolean(getConnection().mset(tuples));
|
||||
} catch (Exception ex) {
|
||||
throw convertLettuceAccessException(ex);
|
||||
}
|
||||
return connection.invoke().from(RedisStringAsyncCommands::mset, tuples).get(Converters.stringToBooleanConverter());
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -296,19 +175,7 @@ class LettuceStringCommands implements RedisStringCommands {
|
||||
|
||||
Assert.notNull(tuples, "Tuples must not be null!");
|
||||
|
||||
try {
|
||||
if (isPipelined()) {
|
||||
pipeline(connection.newLettuceResult(getAsyncConnection().msetnx(tuples)));
|
||||
return null;
|
||||
}
|
||||
if (isQueueing()) {
|
||||
transaction(connection.newLettuceResult(getAsyncConnection().msetnx(tuples)));
|
||||
return null;
|
||||
}
|
||||
return getConnection().msetnx(tuples);
|
||||
} catch (Exception ex) {
|
||||
throw convertLettuceAccessException(ex);
|
||||
}
|
||||
return connection.invoke().just(RedisStringAsyncCommands::msetnx, tuples);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -320,19 +187,7 @@ class LettuceStringCommands implements RedisStringCommands {
|
||||
|
||||
Assert.notNull(key, "Key must not be null!");
|
||||
|
||||
try {
|
||||
if (isPipelined()) {
|
||||
pipeline(connection.newLettuceResult(getAsyncConnection().incr(key)));
|
||||
return null;
|
||||
}
|
||||
if (isQueueing()) {
|
||||
transaction(connection.newLettuceResult(getAsyncConnection().incr(key)));
|
||||
return null;
|
||||
}
|
||||
return getConnection().incr(key);
|
||||
} catch (Exception ex) {
|
||||
throw convertLettuceAccessException(ex);
|
||||
}
|
||||
return connection.invoke().just(RedisStringAsyncCommands::incr, key);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -344,19 +199,7 @@ class LettuceStringCommands implements RedisStringCommands {
|
||||
|
||||
Assert.notNull(key, "Key must not be null!");
|
||||
|
||||
try {
|
||||
if (isPipelined()) {
|
||||
pipeline(connection.newLettuceResult(getAsyncConnection().incrby(key, value)));
|
||||
return null;
|
||||
}
|
||||
if (isQueueing()) {
|
||||
transaction(connection.newLettuceResult(getAsyncConnection().incrby(key, value)));
|
||||
return null;
|
||||
}
|
||||
return getConnection().incrby(key, value);
|
||||
} catch (Exception ex) {
|
||||
throw convertLettuceAccessException(ex);
|
||||
}
|
||||
return connection.invoke().just(RedisStringAsyncCommands::incrby, key, value);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -368,19 +211,7 @@ class LettuceStringCommands implements RedisStringCommands {
|
||||
|
||||
Assert.notNull(key, "Key must not be null!");
|
||||
|
||||
try {
|
||||
if (isPipelined()) {
|
||||
pipeline(connection.newLettuceResult(getAsyncConnection().incrbyfloat(key, value)));
|
||||
return null;
|
||||
}
|
||||
if (isQueueing()) {
|
||||
transaction(connection.newLettuceResult(getAsyncConnection().incrbyfloat(key, value)));
|
||||
return null;
|
||||
}
|
||||
return getConnection().incrbyfloat(key, value);
|
||||
} catch (Exception ex) {
|
||||
throw convertLettuceAccessException(ex);
|
||||
}
|
||||
return connection.invoke().just(RedisStringAsyncCommands::incrbyfloat, key, value);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -392,19 +223,7 @@ class LettuceStringCommands implements RedisStringCommands {
|
||||
|
||||
Assert.notNull(key, "Key must not be null!");
|
||||
|
||||
try {
|
||||
if (isPipelined()) {
|
||||
pipeline(connection.newLettuceResult(getAsyncConnection().decr(key)));
|
||||
return null;
|
||||
}
|
||||
if (isQueueing()) {
|
||||
transaction(connection.newLettuceResult(getAsyncConnection().decr(key)));
|
||||
return null;
|
||||
}
|
||||
return getConnection().decr(key);
|
||||
} catch (Exception ex) {
|
||||
throw convertLettuceAccessException(ex);
|
||||
}
|
||||
return connection.invoke().just(RedisStringAsyncCommands::decr, key);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -416,19 +235,7 @@ class LettuceStringCommands implements RedisStringCommands {
|
||||
|
||||
Assert.notNull(key, "Key must not be null!");
|
||||
|
||||
try {
|
||||
if (isPipelined()) {
|
||||
pipeline(connection.newLettuceResult(getAsyncConnection().decrby(key, value)));
|
||||
return null;
|
||||
}
|
||||
if (isQueueing()) {
|
||||
transaction(connection.newLettuceResult(getAsyncConnection().decrby(key, value)));
|
||||
return null;
|
||||
}
|
||||
return getConnection().decrby(key, value);
|
||||
} catch (Exception ex) {
|
||||
throw convertLettuceAccessException(ex);
|
||||
}
|
||||
return connection.invoke().just(RedisStringAsyncCommands::decrby, key, value);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -441,19 +248,7 @@ class LettuceStringCommands implements RedisStringCommands {
|
||||
Assert.notNull(key, "Key must not be null!");
|
||||
Assert.notNull(value, "Value must not be null!");
|
||||
|
||||
try {
|
||||
if (isPipelined()) {
|
||||
pipeline(connection.newLettuceResult(getAsyncConnection().append(key, value)));
|
||||
return null;
|
||||
}
|
||||
if (isQueueing()) {
|
||||
transaction(connection.newLettuceResult(getAsyncConnection().append(key, value)));
|
||||
return null;
|
||||
}
|
||||
return getConnection().append(key, value);
|
||||
} catch (Exception ex) {
|
||||
throw convertLettuceAccessException(ex);
|
||||
}
|
||||
return connection.invoke().just(RedisStringAsyncCommands::append, key, value);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -465,19 +260,7 @@ class LettuceStringCommands implements RedisStringCommands {
|
||||
|
||||
Assert.notNull(key, "Key must not be null!");
|
||||
|
||||
try {
|
||||
if (isPipelined()) {
|
||||
pipeline(connection.newLettuceResult(getAsyncConnection().getrange(key, start, end)));
|
||||
return null;
|
||||
}
|
||||
if (isQueueing()) {
|
||||
transaction(connection.newLettuceResult(getAsyncConnection().getrange(key, start, end)));
|
||||
return null;
|
||||
}
|
||||
return getConnection().getrange(key, start, end);
|
||||
} catch (Exception ex) {
|
||||
throw convertLettuceAccessException(ex);
|
||||
}
|
||||
return connection.invoke().just(RedisStringAsyncCommands::getrange, key, start, end);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -490,19 +273,7 @@ class LettuceStringCommands implements RedisStringCommands {
|
||||
Assert.notNull(key, "Key must not be null!");
|
||||
Assert.notNull(value, "Value must not be null!");
|
||||
|
||||
try {
|
||||
if (isPipelined()) {
|
||||
pipeline(connection.newLettuceStatusResult(getAsyncConnection().setrange(key, offset, value)));
|
||||
return;
|
||||
}
|
||||
if (isQueueing()) {
|
||||
transaction(connection.newLettuceStatusResult(getAsyncConnection().setrange(key, offset, value)));
|
||||
return;
|
||||
}
|
||||
getConnection().setrange(key, offset, value);
|
||||
} catch (Exception ex) {
|
||||
throw convertLettuceAccessException(ex);
|
||||
}
|
||||
connection.invokeStatus().just(RedisStringAsyncCommands::setrange, key, offset, value);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -514,21 +285,8 @@ class LettuceStringCommands implements RedisStringCommands {
|
||||
|
||||
Assert.notNull(key, "Key must not be null!");
|
||||
|
||||
try {
|
||||
if (isPipelined()) {
|
||||
pipeline(
|
||||
connection.newLettuceResult(getAsyncConnection().getbit(key, offset), LettuceConverters.longToBoolean()));
|
||||
return null;
|
||||
}
|
||||
if (isQueueing()) {
|
||||
transaction(
|
||||
connection.newLettuceResult(getAsyncConnection().getbit(key, offset), LettuceConverters.longToBoolean()));
|
||||
return null;
|
||||
}
|
||||
return LettuceConverters.toBoolean(getConnection().getbit(key, offset));
|
||||
} catch (Exception ex) {
|
||||
throw convertLettuceAccessException(ex);
|
||||
}
|
||||
return connection.invoke().from(RedisStringAsyncCommands::getbit, key, offset)
|
||||
.get(LettuceConverters.longToBoolean());
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -540,23 +298,8 @@ class LettuceStringCommands implements RedisStringCommands {
|
||||
|
||||
Assert.notNull(key, "Key must not be null!");
|
||||
|
||||
try {
|
||||
if (isPipelined()) {
|
||||
pipeline(connection.newLettuceResult(getAsyncConnection().setbit(key, offset, LettuceConverters.toInt(value)),
|
||||
LettuceConverters.longToBooleanConverter()));
|
||||
return null;
|
||||
}
|
||||
if (isQueueing()) {
|
||||
transaction(
|
||||
connection.newLettuceResult(getAsyncConnection().setbit(key, offset, LettuceConverters.toInt(value)),
|
||||
LettuceConverters.longToBooleanConverter()));
|
||||
return null;
|
||||
}
|
||||
return LettuceConverters.longToBooleanConverter()
|
||||
.convert(getConnection().setbit(key, offset, LettuceConverters.toInt(value)));
|
||||
} catch (Exception ex) {
|
||||
throw convertLettuceAccessException(ex);
|
||||
}
|
||||
return connection.invoke().from(RedisStringAsyncCommands::setbit, key, offset, LettuceConverters.toInt(value))
|
||||
.get(LettuceConverters.longToBoolean());
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -568,19 +311,7 @@ class LettuceStringCommands implements RedisStringCommands {
|
||||
|
||||
Assert.notNull(key, "Key must not be null!");
|
||||
|
||||
try {
|
||||
if (isPipelined()) {
|
||||
pipeline(connection.newLettuceResult(getAsyncConnection().bitcount(key)));
|
||||
return null;
|
||||
}
|
||||
if (isQueueing()) {
|
||||
transaction(connection.newLettuceResult(getAsyncConnection().bitcount(key)));
|
||||
return null;
|
||||
}
|
||||
return getConnection().bitcount(key);
|
||||
} catch (Exception ex) {
|
||||
throw convertLettuceAccessException(ex);
|
||||
}
|
||||
return connection.invoke().just(RedisStringAsyncCommands::bitcount, key);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -592,19 +323,7 @@ class LettuceStringCommands implements RedisStringCommands {
|
||||
|
||||
Assert.notNull(key, "Key must not be null!");
|
||||
|
||||
try {
|
||||
if (isPipelined()) {
|
||||
pipeline(connection.newLettuceResult(getAsyncConnection().bitcount(key, start, end)));
|
||||
return null;
|
||||
}
|
||||
if (isQueueing()) {
|
||||
transaction(connection.newLettuceResult(getAsyncConnection().bitcount(key, start, end)));
|
||||
return null;
|
||||
}
|
||||
return getConnection().bitcount(key, start, end);
|
||||
} catch (Exception ex) {
|
||||
throw convertLettuceAccessException(ex);
|
||||
}
|
||||
return connection.invoke().just(RedisStringAsyncCommands::bitcount, key, start, end);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -619,19 +338,7 @@ class LettuceStringCommands implements RedisStringCommands {
|
||||
|
||||
BitFieldArgs args = LettuceConverters.toBitFieldArgs(subCommands);
|
||||
|
||||
try {
|
||||
if (isPipelined()) {
|
||||
pipeline(connection.newLettuceResult(getAsyncConnection().bitfield(key, args)));
|
||||
return null;
|
||||
}
|
||||
if (isQueueing()) {
|
||||
transaction(connection.newLettuceResult(getAsyncConnection().bitfield(key, args)));
|
||||
return null;
|
||||
}
|
||||
return getConnection().bitfield(key, args);
|
||||
} catch (Exception ex) {
|
||||
throw convertLettuceAccessException(ex);
|
||||
}
|
||||
return connection.invoke().just(RedisStringAsyncCommands::bitfield, key, args);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -647,57 +354,25 @@ class LettuceStringCommands implements RedisStringCommands {
|
||||
if (op == BitOperation.NOT && keys.length > 1) {
|
||||
throw new UnsupportedOperationException("Bitop NOT should only be performed against one key");
|
||||
}
|
||||
try {
|
||||
if (isPipelined()) {
|
||||
pipeline(connection.newLettuceResult(asyncBitOp(op, destination, keys)));
|
||||
return null;
|
||||
}
|
||||
if (isQueueing()) {
|
||||
transaction(connection.newLettuceResult(asyncBitOp(op, destination, keys)));
|
||||
return null;
|
||||
}
|
||||
return syncBitOp(op, destination, keys);
|
||||
} catch (UnsupportedOperationException ex) {
|
||||
throw ex;
|
||||
} catch (Exception ex) {
|
||||
throw convertLettuceAccessException(ex);
|
||||
}
|
||||
}
|
||||
|
||||
private Future<Long> asyncBitOp(BitOperation op, byte[] destination, byte[]... keys) {
|
||||
switch (op) {
|
||||
case AND:
|
||||
return getAsyncConnection().bitopAnd(destination, keys);
|
||||
case OR:
|
||||
return getAsyncConnection().bitopOr(destination, keys);
|
||||
case XOR:
|
||||
return getAsyncConnection().bitopXor(destination, keys);
|
||||
case NOT:
|
||||
if (keys.length != 1) {
|
||||
throw new UnsupportedOperationException("Bitop NOT should only be performed against one key");
|
||||
}
|
||||
return getAsyncConnection().bitopNot(destination, keys[0]);
|
||||
default:
|
||||
throw new UnsupportedOperationException("Bit operation " + op + " is not supported");
|
||||
}
|
||||
}
|
||||
return connection.invoke().just(it -> {
|
||||
|
||||
private Long syncBitOp(BitOperation op, byte[] destination, byte[]... keys) {
|
||||
switch (op) {
|
||||
case AND:
|
||||
return getConnection().bitopAnd(destination, keys);
|
||||
case OR:
|
||||
return getConnection().bitopOr(destination, keys);
|
||||
case XOR:
|
||||
return getConnection().bitopXor(destination, keys);
|
||||
case NOT:
|
||||
if (keys.length != 1) {
|
||||
throw new UnsupportedOperationException("Bitop NOT should only be performed against one key");
|
||||
}
|
||||
return getConnection().bitopNot(destination, keys[0]);
|
||||
default:
|
||||
throw new UnsupportedOperationException("Bit operation " + op + " is not supported");
|
||||
}
|
||||
switch (op) {
|
||||
case AND:
|
||||
return it.bitopAnd(destination, keys);
|
||||
case OR:
|
||||
return it.bitopOr(destination, keys);
|
||||
case XOR:
|
||||
return it.bitopXor(destination, keys);
|
||||
case NOT:
|
||||
if (keys.length != 1) {
|
||||
throw new UnsupportedOperationException("Bitop NOT should only be performed against one key");
|
||||
}
|
||||
return it.bitopNot(destination, keys[0]);
|
||||
default:
|
||||
throw new UnsupportedOperationException("Bit operation " + op + " is not supported");
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -711,41 +386,17 @@ class LettuceStringCommands implements RedisStringCommands {
|
||||
Assert.notNull(key, "Key must not be null!");
|
||||
Assert.notNull(range, "Range must not be null! Use Range.unbounded() instead.");
|
||||
|
||||
try {
|
||||
if (isPipelined() || isQueueing()) {
|
||||
if (range.getLowerBound().isBounded()) {
|
||||
|
||||
RedisFuture<Long> futureResult;
|
||||
RedisClusterAsyncCommands<byte[], byte[]> connection = getAsyncConnection();
|
||||
|
||||
if (range.getLowerBound().isBounded()) {
|
||||
if (range.getUpperBound().isBounded()) {
|
||||
futureResult = connection.bitpos(key, bit, getLowerValue(range), getUpperValue(range));
|
||||
} else {
|
||||
futureResult = connection.bitpos(key, bit, getLowerValue(range));
|
||||
}
|
||||
} else {
|
||||
futureResult = connection.bitpos(key, bit);
|
||||
}
|
||||
|
||||
if (isPipelined()) {
|
||||
pipeline(this.connection.newLettuceResult(futureResult));
|
||||
} else if (isQueueing()) {
|
||||
transaction(this.connection.newLettuceResult(futureResult));
|
||||
}
|
||||
return null;
|
||||
if (range.getUpperBound().isBounded()) {
|
||||
return connection.invoke().just(RedisStringAsyncCommands::bitpos, key, bit, getLowerValue(range),
|
||||
getUpperValue(range));
|
||||
}
|
||||
|
||||
if (range.getLowerBound().isBounded()) {
|
||||
if (range.getUpperBound().isBounded()) {
|
||||
return getConnection().bitpos(key, bit, getLowerValue(range), getUpperValue(range));
|
||||
}
|
||||
return getConnection().bitpos(key, bit, getLowerValue(range));
|
||||
}
|
||||
|
||||
return getConnection().bitpos(key, bit);
|
||||
} catch (Exception ex) {
|
||||
throw convertLettuceAccessException(ex);
|
||||
return connection.invoke().just(RedisStringAsyncCommands::bitpos, key, bit, getLowerValue(range));
|
||||
}
|
||||
|
||||
return connection.invoke().just(RedisStringAsyncCommands::bitpos, key, bit);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -757,47 +408,7 @@ class LettuceStringCommands implements RedisStringCommands {
|
||||
|
||||
Assert.notNull(key, "Key must not be null!");
|
||||
|
||||
try {
|
||||
if (isPipelined()) {
|
||||
pipeline(connection.newLettuceResult(getAsyncConnection().strlen(key)));
|
||||
return null;
|
||||
}
|
||||
if (isQueueing()) {
|
||||
transaction(connection.newLettuceResult(getAsyncConnection().strlen(key)));
|
||||
return null;
|
||||
}
|
||||
return getConnection().strlen(key);
|
||||
} catch (Exception ex) {
|
||||
throw convertLettuceAccessException(ex);
|
||||
}
|
||||
}
|
||||
|
||||
private boolean isPipelined() {
|
||||
return connection.isPipelined();
|
||||
}
|
||||
|
||||
private boolean isQueueing() {
|
||||
return connection.isQueueing();
|
||||
}
|
||||
|
||||
private void pipeline(LettuceResult result) {
|
||||
connection.pipeline(result);
|
||||
}
|
||||
|
||||
private void transaction(LettuceResult result) {
|
||||
connection.transaction(result);
|
||||
}
|
||||
|
||||
RedisClusterAsyncCommands<byte[], byte[]> getAsyncConnection() {
|
||||
return connection.getAsyncConnection();
|
||||
}
|
||||
|
||||
public RedisClusterCommands<byte[], byte[]> getConnection() {
|
||||
return connection.getConnection();
|
||||
}
|
||||
|
||||
private DataAccessException convertLettuceAccessException(Exception ex) {
|
||||
return connection.convertLettuceAccessException(ex);
|
||||
return connection.invoke().just(RedisStringAsyncCommands::strlen, key);
|
||||
}
|
||||
|
||||
private static <T extends Comparable<T>> T getUpperValue(Range<T> range) {
|
||||
|
||||
@@ -19,13 +19,12 @@ import io.lettuce.core.ScanArgs;
|
||||
import io.lettuce.core.ScoredValue;
|
||||
import io.lettuce.core.ScoredValueScanCursor;
|
||||
import io.lettuce.core.ZStoreArgs;
|
||||
import io.lettuce.core.cluster.api.async.RedisClusterAsyncCommands;
|
||||
import io.lettuce.core.api.async.RedisSortedSetAsyncCommands;
|
||||
import io.lettuce.core.cluster.api.sync.RedisClusterCommands;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
import org.springframework.dao.DataAccessException;
|
||||
import org.springframework.data.redis.connection.RedisZSetCommands;
|
||||
import org.springframework.data.redis.core.Cursor;
|
||||
import org.springframework.data.redis.core.KeyBoundCursor;
|
||||
@@ -58,21 +57,8 @@ class LettuceZSetCommands implements RedisZSetCommands {
|
||||
Assert.notNull(key, "Key must not be null!");
|
||||
Assert.notNull(value, "Value must not be null!");
|
||||
|
||||
try {
|
||||
if (isPipelined()) {
|
||||
pipeline(connection.newLettuceResult(getAsyncConnection().zadd(key, score, value),
|
||||
LettuceConverters.longToBoolean()));
|
||||
return null;
|
||||
}
|
||||
if (isQueueing()) {
|
||||
transaction(connection.newLettuceResult(getAsyncConnection().zadd(key, score, value),
|
||||
LettuceConverters.longToBoolean()));
|
||||
return null;
|
||||
}
|
||||
return LettuceConverters.toBoolean(getConnection().zadd(key, score, value));
|
||||
} catch (Exception ex) {
|
||||
throw convertLettuceAccessException(ex);
|
||||
}
|
||||
return connection.invoke().from(RedisSortedSetAsyncCommands::zadd, key, score, value)
|
||||
.get(LettuceConverters.longToBoolean());
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -85,21 +71,8 @@ class LettuceZSetCommands implements RedisZSetCommands {
|
||||
Assert.notNull(key, "Key must not be null!");
|
||||
Assert.notNull(tuples, "Tuples must not be null!");
|
||||
|
||||
try {
|
||||
if (isPipelined()) {
|
||||
pipeline(
|
||||
connection.newLettuceResult(getAsyncConnection().zadd(key, LettuceConverters.toObjects(tuples).toArray())));
|
||||
return null;
|
||||
}
|
||||
if (isQueueing()) {
|
||||
transaction(
|
||||
connection.newLettuceResult(getAsyncConnection().zadd(key, LettuceConverters.toObjects(tuples).toArray())));
|
||||
return null;
|
||||
}
|
||||
return getConnection().zadd(key, LettuceConverters.toObjects(tuples).toArray());
|
||||
} catch (Exception ex) {
|
||||
throw convertLettuceAccessException(ex);
|
||||
}
|
||||
return connection.invoke().just(RedisSortedSetAsyncCommands::zadd, key,
|
||||
LettuceConverters.toObjects(tuples).toArray());
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -113,19 +86,7 @@ class LettuceZSetCommands implements RedisZSetCommands {
|
||||
Assert.notNull(values, "Values must not be null!");
|
||||
Assert.noNullElements(values, "Values must not contain null elements!");
|
||||
|
||||
try {
|
||||
if (isPipelined()) {
|
||||
pipeline(connection.newLettuceResult(getAsyncConnection().zrem(key, values)));
|
||||
return null;
|
||||
}
|
||||
if (isQueueing()) {
|
||||
transaction(connection.newLettuceResult(getAsyncConnection().zrem(key, values)));
|
||||
return null;
|
||||
}
|
||||
return getConnection().zrem(key, values);
|
||||
} catch (Exception ex) {
|
||||
throw convertLettuceAccessException(ex);
|
||||
}
|
||||
return connection.invoke().just(RedisSortedSetAsyncCommands::zrem, key, values);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -138,19 +99,7 @@ class LettuceZSetCommands implements RedisZSetCommands {
|
||||
Assert.notNull(key, "Key must not be null!");
|
||||
Assert.notNull(value, "Value must not be null!");
|
||||
|
||||
try {
|
||||
if (isPipelined()) {
|
||||
pipeline(connection.newLettuceResult(getAsyncConnection().zincrby(key, increment, value)));
|
||||
return null;
|
||||
}
|
||||
if (isQueueing()) {
|
||||
transaction(connection.newLettuceResult(getAsyncConnection().zincrby(key, increment, value)));
|
||||
return null;
|
||||
}
|
||||
return getConnection().zincrby(key, increment, value);
|
||||
} catch (Exception ex) {
|
||||
throw convertLettuceAccessException(ex);
|
||||
}
|
||||
return connection.invoke().just(RedisSortedSetAsyncCommands::zincrby, key, increment, value);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -163,19 +112,7 @@ class LettuceZSetCommands implements RedisZSetCommands {
|
||||
Assert.notNull(key, "Key must not be null!");
|
||||
Assert.notNull(value, "Value must not be null!");
|
||||
|
||||
try {
|
||||
if (isPipelined()) {
|
||||
pipeline(connection.newLettuceResult(getAsyncConnection().zrank(key, value)));
|
||||
return null;
|
||||
}
|
||||
if (isQueueing()) {
|
||||
transaction(connection.newLettuceResult(getAsyncConnection().zrank(key, value)));
|
||||
return null;
|
||||
}
|
||||
return getConnection().zrank(key, value);
|
||||
} catch (Exception ex) {
|
||||
throw convertLettuceAccessException(ex);
|
||||
}
|
||||
return connection.invoke().just(RedisSortedSetAsyncCommands::zrank, key, value);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -187,19 +124,7 @@ class LettuceZSetCommands implements RedisZSetCommands {
|
||||
|
||||
Assert.notNull(key, "Key must not be null!");
|
||||
|
||||
try {
|
||||
if (isPipelined()) {
|
||||
pipeline(connection.newLettuceResult(getAsyncConnection().zrevrank(key, value)));
|
||||
return null;
|
||||
}
|
||||
if (isQueueing()) {
|
||||
transaction(connection.newLettuceResult(getAsyncConnection().zrevrank(key, value)));
|
||||
return null;
|
||||
}
|
||||
return getConnection().zrevrank(key, value);
|
||||
} catch (Exception ex) {
|
||||
throw convertLettuceAccessException(ex);
|
||||
}
|
||||
return connection.invoke().just(RedisSortedSetAsyncCommands::zrevrank, key, value);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -211,21 +136,7 @@ class LettuceZSetCommands implements RedisZSetCommands {
|
||||
|
||||
Assert.notNull(key, "Key must not be null!");
|
||||
|
||||
try {
|
||||
if (isPipelined()) {
|
||||
pipeline(connection.newLettuceResult(getAsyncConnection().zrange(key, start, end),
|
||||
LettuceConverters.bytesListToBytesSet()));
|
||||
return null;
|
||||
}
|
||||
if (isQueueing()) {
|
||||
transaction(connection.newLettuceResult(getAsyncConnection().zrange(key, start, end),
|
||||
LettuceConverters.bytesListToBytesSet()));
|
||||
return null;
|
||||
}
|
||||
return LettuceConverters.toBytesSet(getConnection().zrange(key, start, end));
|
||||
} catch (Exception ex) {
|
||||
throw convertLettuceAccessException(ex);
|
||||
}
|
||||
return connection.invoke().fromMany(RedisSortedSetAsyncCommands::zrange, key, start, end).toSet();
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -237,21 +148,8 @@ class LettuceZSetCommands implements RedisZSetCommands {
|
||||
|
||||
Assert.notNull(key, "Key must not be null!");
|
||||
|
||||
try {
|
||||
if (isPipelined()) {
|
||||
pipeline(connection.newLettuceResult(getAsyncConnection().zrangeWithScores(key, start, end),
|
||||
LettuceConverters.scoredValuesToTupleSet()));
|
||||
return null;
|
||||
}
|
||||
if (isQueueing()) {
|
||||
transaction(connection.newLettuceResult(getAsyncConnection().zrangeWithScores(key, start, end),
|
||||
LettuceConverters.scoredValuesToTupleSet()));
|
||||
return null;
|
||||
}
|
||||
return LettuceConverters.toTupleSet(getConnection().zrangeWithScores(key, start, end));
|
||||
} catch (Exception ex) {
|
||||
throw convertLettuceAccessException(ex);
|
||||
}
|
||||
return connection.invoke().fromMany(RedisSortedSetAsyncCommands::zrangeWithScores, key, start, end)
|
||||
.toSet(LettuceConverters::toTuple);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -265,40 +163,16 @@ class LettuceZSetCommands implements RedisZSetCommands {
|
||||
Assert.notNull(range, "Range for ZRANGEBYSCOREWITHSCORES must not be null!");
|
||||
Assert.notNull(limit, "Limit must not be null!");
|
||||
|
||||
try {
|
||||
if (isPipelined()) {
|
||||
if (limit.isUnlimited()) {
|
||||
pipeline(connection.newLettuceResult(
|
||||
getAsyncConnection().zrangebyscoreWithScores(key, LettuceConverters.toRange(range)),
|
||||
LettuceConverters.scoredValuesToTupleSet()));
|
||||
} else {
|
||||
pipeline(connection.newLettuceResult(getAsyncConnection().zrangebyscoreWithScores(key,
|
||||
LettuceConverters.toRange(range), LettuceConverters.toLimit(limit)),
|
||||
LettuceConverters.scoredValuesToTupleSet()));
|
||||
return connection.invoke().fromMany(RedisSortedSetAsyncCommands::zrangebyscoreWithScores, key,
|
||||
LettuceConverters.<Number> toRange(range)).toSet(LettuceConverters::toTuple);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
if (isQueueing()) {
|
||||
if (limit.isUnlimited()) {
|
||||
transaction(connection.newLettuceResult(
|
||||
getAsyncConnection().zrangebyscoreWithScores(key, LettuceConverters.toRange(range)),
|
||||
LettuceConverters.scoredValuesToTupleSet()));
|
||||
} else {
|
||||
transaction(connection.newLettuceResult(getAsyncConnection().zrangebyscoreWithScores(key,
|
||||
LettuceConverters.toRange(range), LettuceConverters.toLimit(limit)),
|
||||
LettuceConverters.scoredValuesToTupleSet()));
|
||||
}
|
||||
return null;
|
||||
}
|
||||
if (limit.isUnlimited()) {
|
||||
return LettuceConverters
|
||||
.toTupleSet(getConnection().zrangebyscoreWithScores(key, LettuceConverters.toRange(range)));
|
||||
}
|
||||
return LettuceConverters.toTupleSet(getConnection().zrangebyscoreWithScores(key, LettuceConverters.toRange(range),
|
||||
LettuceConverters.toLimit(limit)));
|
||||
} catch (Exception ex) {
|
||||
throw convertLettuceAccessException(ex);
|
||||
}
|
||||
|
||||
return connection.invoke()
|
||||
.fromMany(RedisSortedSetAsyncCommands::zrangebyscoreWithScores, key,
|
||||
LettuceConverters.<Number> toRange(range), LettuceConverters.toLimit(limit))
|
||||
.toSet(LettuceConverters::toTuple);
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -310,21 +184,8 @@ class LettuceZSetCommands implements RedisZSetCommands {
|
||||
|
||||
Assert.notNull(key, "Key must not be null!");
|
||||
|
||||
try {
|
||||
if (isPipelined()) {
|
||||
pipeline(connection.newLettuceResult(getAsyncConnection().zrevrange(key, start, end),
|
||||
LettuceConverters.bytesListToBytesSet()));
|
||||
return null;
|
||||
}
|
||||
if (isQueueing()) {
|
||||
transaction(connection.newLettuceResult(getAsyncConnection().zrevrange(key, start, end),
|
||||
LettuceConverters.bytesListToBytesSet()));
|
||||
return null;
|
||||
}
|
||||
return LettuceConverters.toBytesSet(getConnection().zrevrange(key, start, end));
|
||||
} catch (Exception ex) {
|
||||
throw convertLettuceAccessException(ex);
|
||||
}
|
||||
return connection.invoke().fromMany(RedisSortedSetAsyncCommands::zrevrange, key, start, end)
|
||||
.toSet(LettuceInvoker.identityConverter());
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -336,21 +197,8 @@ class LettuceZSetCommands implements RedisZSetCommands {
|
||||
|
||||
Assert.notNull(key, "Key must not be null!");
|
||||
|
||||
try {
|
||||
if (isPipelined()) {
|
||||
pipeline(connection.newLettuceResult(getAsyncConnection().zrevrangeWithScores(key, start, end),
|
||||
LettuceConverters.scoredValuesToTupleSet()));
|
||||
return null;
|
||||
}
|
||||
if (isQueueing()) {
|
||||
transaction(connection.newLettuceResult(getAsyncConnection().zrevrangeWithScores(key, start, end),
|
||||
LettuceConverters.scoredValuesToTupleSet()));
|
||||
return null;
|
||||
}
|
||||
return LettuceConverters.toTupleSet(getConnection().zrevrangeWithScores(key, start, end));
|
||||
} catch (Exception ex) {
|
||||
throw convertLettuceAccessException(ex);
|
||||
}
|
||||
return connection.invoke().fromMany(RedisSortedSetAsyncCommands::zrevrangeWithScores, key, start, end)
|
||||
.toSet(LettuceConverters::toTuple);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -364,39 +212,16 @@ class LettuceZSetCommands implements RedisZSetCommands {
|
||||
Assert.notNull(range, "Range for ZREVRANGEBYSCORE must not be null!");
|
||||
Assert.notNull(limit, "Limit must not be null!");
|
||||
|
||||
try {
|
||||
if (isPipelined()) {
|
||||
if (limit.isUnlimited()) {
|
||||
pipeline(
|
||||
connection.newLettuceResult(getAsyncConnection().zrevrangebyscore(key, LettuceConverters.toRange(range)),
|
||||
LettuceConverters.bytesListToBytesSet()));
|
||||
} else {
|
||||
pipeline(
|
||||
connection.newLettuceResult(getAsyncConnection().zrevrangebyscore(key, LettuceConverters.toRange(range),
|
||||
LettuceConverters.toLimit(limit)), LettuceConverters.bytesListToBytesSet()));
|
||||
|
||||
return connection.invoke()
|
||||
.fromMany(RedisSortedSetAsyncCommands::zrevrangebyscore, key, LettuceConverters.<Number> toRange(range))
|
||||
.toSet();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
if (isQueueing()) {
|
||||
if (limit.isUnlimited()) {
|
||||
transaction(
|
||||
connection.newLettuceResult(getAsyncConnection().zrevrangebyscore(key, LettuceConverters.toRange(range)),
|
||||
LettuceConverters.bytesListToBytesSet()));
|
||||
} else {
|
||||
transaction(
|
||||
connection.newLettuceResult(getAsyncConnection().zrevrangebyscore(key, LettuceConverters.toRange(range),
|
||||
LettuceConverters.toLimit(limit)), LettuceConverters.bytesListToBytesSet()));
|
||||
}
|
||||
return null;
|
||||
}
|
||||
if (limit.isUnlimited()) {
|
||||
return LettuceConverters.toBytesSet(getConnection().zrevrangebyscore(key, LettuceConverters.toRange(range)));
|
||||
}
|
||||
return LettuceConverters.toBytesSet(
|
||||
getConnection().zrevrangebyscore(key, LettuceConverters.toRange(range), LettuceConverters.toLimit(limit)));
|
||||
} catch (Exception ex) {
|
||||
throw convertLettuceAccessException(ex);
|
||||
}
|
||||
|
||||
return connection.invoke().fromMany(RedisSortedSetAsyncCommands::zrevrangebyscore, key,
|
||||
LettuceConverters.<Number> toRange(range), LettuceConverters.toLimit(limit)).toSet();
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -410,41 +235,16 @@ class LettuceZSetCommands implements RedisZSetCommands {
|
||||
Assert.notNull(range, "Range for ZREVRANGEBYSCOREWITHSCORES must not be null!");
|
||||
Assert.notNull(limit, "Limit must not be null!");
|
||||
|
||||
try {
|
||||
if (isPipelined()) {
|
||||
if (limit.isUnlimited()) {
|
||||
pipeline(connection.newLettuceResult(
|
||||
getAsyncConnection().zrevrangebyscoreWithScores(key, LettuceConverters.toRange(range)),
|
||||
LettuceConverters.scoredValuesToTupleSet()));
|
||||
} else {
|
||||
pipeline(connection.newLettuceResult(getAsyncConnection().zrevrangebyscoreWithScores(key,
|
||||
LettuceConverters.toRange(range), LettuceConverters.toLimit(limit)),
|
||||
LettuceConverters.scoredValuesToTupleSet()));
|
||||
return connection.invoke().fromMany(RedisSortedSetAsyncCommands::zrevrangebyscoreWithScores, key,
|
||||
LettuceConverters.<Number> toRange(range)).toSet(LettuceConverters::toTuple);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
if (isQueueing()) {
|
||||
if (limit.isUnlimited()) {
|
||||
transaction(connection.newLettuceResult(
|
||||
getAsyncConnection().zrevrangebyscoreWithScores(key, LettuceConverters.toRange(range)),
|
||||
LettuceConverters.scoredValuesToTupleSet()));
|
||||
} else {
|
||||
transaction(connection.newLettuceResult(getAsyncConnection().zrevrangebyscoreWithScores(key,
|
||||
LettuceConverters.toRange(range), LettuceConverters.toLimit(limit)),
|
||||
LettuceConverters.scoredValuesToTupleSet()));
|
||||
}
|
||||
return null;
|
||||
}
|
||||
if (limit.isUnlimited()) {
|
||||
return LettuceConverters
|
||||
.toTupleSet(getConnection().zrevrangebyscoreWithScores(key, LettuceConverters.toRange(range)));
|
||||
}
|
||||
return LettuceConverters.toTupleSet(getConnection().zrevrangebyscoreWithScores(key,
|
||||
LettuceConverters.toRange(range), LettuceConverters.toLimit(limit)));
|
||||
} catch (Exception ex) {
|
||||
throw convertLettuceAccessException(ex);
|
||||
}
|
||||
return connection.invoke()
|
||||
.fromMany(RedisSortedSetAsyncCommands::zrevrangebyscoreWithScores, key,
|
||||
LettuceConverters.<Number> toRange(range), LettuceConverters.toLimit(limit))
|
||||
.toSet(LettuceConverters::toTuple);
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -456,19 +256,8 @@ class LettuceZSetCommands implements RedisZSetCommands {
|
||||
|
||||
Assert.notNull(key, "Key must not be null!");
|
||||
|
||||
try {
|
||||
if (isPipelined()) {
|
||||
pipeline(connection.newLettuceResult(getAsyncConnection().zcount(key, LettuceConverters.toRange(range))));
|
||||
return null;
|
||||
}
|
||||
if (isQueueing()) {
|
||||
transaction(connection.newLettuceResult(getAsyncConnection().zcount(key, LettuceConverters.toRange(range))));
|
||||
return null;
|
||||
}
|
||||
return getConnection().zcount(key, LettuceConverters.toRange(range));
|
||||
} catch (Exception ex) {
|
||||
throw convertLettuceAccessException(ex);
|
||||
}
|
||||
return connection.invoke().just(RedisSortedSetAsyncCommands::zcount, key,
|
||||
LettuceConverters.<Number> toRange(range));
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -481,19 +270,8 @@ class LettuceZSetCommands implements RedisZSetCommands {
|
||||
Assert.notNull(key, "Key must not be null!");
|
||||
Assert.notNull(range, "Range must not be null!");
|
||||
|
||||
try {
|
||||
if (isPipelined()) {
|
||||
pipeline(connection.newLettuceResult(getAsyncConnection().zlexcount(key, LettuceConverters.toRange(range))));
|
||||
return null;
|
||||
}
|
||||
if (isQueueing()) {
|
||||
transaction(connection.newLettuceResult(getAsyncConnection().zlexcount(key, LettuceConverters.toRange(range))));
|
||||
return null;
|
||||
}
|
||||
return getConnection().zlexcount(key, LettuceConverters.toRange(range, true));
|
||||
} catch (Exception ex) {
|
||||
throw convertLettuceAccessException(ex);
|
||||
}
|
||||
return connection.invoke().just(RedisSortedSetAsyncCommands::zlexcount, key,
|
||||
LettuceConverters.<byte[]> toRange(range, true));
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -505,19 +283,7 @@ class LettuceZSetCommands implements RedisZSetCommands {
|
||||
|
||||
Assert.notNull(key, "Key must not be null!");
|
||||
|
||||
try {
|
||||
if (isPipelined()) {
|
||||
pipeline(connection.newLettuceResult(getAsyncConnection().zcard(key)));
|
||||
return null;
|
||||
}
|
||||
if (isQueueing()) {
|
||||
transaction(connection.newLettuceResult(getAsyncConnection().zcard(key)));
|
||||
return null;
|
||||
}
|
||||
return getConnection().zcard(key);
|
||||
} catch (Exception ex) {
|
||||
throw convertLettuceAccessException(ex);
|
||||
}
|
||||
return connection.invoke().just(RedisSortedSetAsyncCommands::zcard, key);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -530,19 +296,7 @@ class LettuceZSetCommands implements RedisZSetCommands {
|
||||
Assert.notNull(key, "Key must not be null!");
|
||||
Assert.notNull(value, "Value must not be null!");
|
||||
|
||||
try {
|
||||
if (isPipelined()) {
|
||||
pipeline(connection.newLettuceResult(getAsyncConnection().zscore(key, value)));
|
||||
return null;
|
||||
}
|
||||
if (isQueueing()) {
|
||||
transaction(connection.newLettuceResult(getAsyncConnection().zscore(key, value)));
|
||||
return null;
|
||||
}
|
||||
return getConnection().zscore(key, value);
|
||||
} catch (Exception ex) {
|
||||
throw convertLettuceAccessException(ex);
|
||||
}
|
||||
return connection.invoke().just(RedisSortedSetAsyncCommands::zscore, key, value);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -554,19 +308,7 @@ class LettuceZSetCommands implements RedisZSetCommands {
|
||||
|
||||
Assert.notNull(key, "Key must not be null!");
|
||||
|
||||
try {
|
||||
if (isPipelined()) {
|
||||
pipeline(connection.newLettuceResult(getAsyncConnection().zremrangebyrank(key, start, end)));
|
||||
return null;
|
||||
}
|
||||
if (isQueueing()) {
|
||||
transaction(connection.newLettuceResult(getAsyncConnection().zremrangebyrank(key, start, end)));
|
||||
return null;
|
||||
}
|
||||
return getConnection().zremrangebyrank(key, start, end);
|
||||
} catch (Exception ex) {
|
||||
throw convertLettuceAccessException(ex);
|
||||
}
|
||||
return connection.invoke().just(RedisSortedSetAsyncCommands::zremrangebyrank, key, start, end);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -579,21 +321,8 @@ class LettuceZSetCommands implements RedisZSetCommands {
|
||||
Assert.notNull(key, "Key must not be null!");
|
||||
Assert.notNull(range, "Range for ZREMRANGEBYSCORE must not be null!");
|
||||
|
||||
try {
|
||||
if (isPipelined()) {
|
||||
pipeline(
|
||||
connection.newLettuceResult(getAsyncConnection().zremrangebyscore(key, LettuceConverters.toRange(range))));
|
||||
return null;
|
||||
}
|
||||
if (isQueueing()) {
|
||||
transaction(
|
||||
connection.newLettuceResult(getAsyncConnection().zremrangebyscore(key, LettuceConverters.toRange(range))));
|
||||
return null;
|
||||
}
|
||||
return getConnection().zremrangebyscore(key, LettuceConverters.toRange(range));
|
||||
} catch (Exception ex) {
|
||||
throw convertLettuceAccessException(ex);
|
||||
}
|
||||
return connection.invoke().just(RedisSortedSetAsyncCommands::zremrangebyscore, key,
|
||||
LettuceConverters.<Number> toRange(range));
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -611,19 +340,7 @@ class LettuceZSetCommands implements RedisZSetCommands {
|
||||
|
||||
ZStoreArgs storeArgs = zStoreArgs(aggregate, weights);
|
||||
|
||||
try {
|
||||
if (isPipelined()) {
|
||||
pipeline(connection.newLettuceResult(getAsyncConnection().zunionstore(destKey, storeArgs, sets)));
|
||||
return null;
|
||||
}
|
||||
if (isQueueing()) {
|
||||
transaction(connection.newLettuceResult(getAsyncConnection().zunionstore(destKey, storeArgs, sets)));
|
||||
return null;
|
||||
}
|
||||
return getConnection().zunionstore(destKey, storeArgs, sets);
|
||||
} catch (Exception ex) {
|
||||
throw convertLettuceAccessException(ex);
|
||||
}
|
||||
return connection.invoke().just(RedisSortedSetAsyncCommands::zunionstore, destKey, storeArgs, sets);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -637,19 +354,7 @@ class LettuceZSetCommands implements RedisZSetCommands {
|
||||
Assert.notNull(sets, "Source sets must not be null!");
|
||||
Assert.noNullElements(sets, "Source sets must not contain null elements!");
|
||||
|
||||
try {
|
||||
if (isPipelined()) {
|
||||
pipeline(connection.newLettuceResult(getAsyncConnection().zunionstore(destKey, sets)));
|
||||
return null;
|
||||
}
|
||||
if (isQueueing()) {
|
||||
transaction(connection.newLettuceResult(getAsyncConnection().zunionstore(destKey, sets)));
|
||||
return null;
|
||||
}
|
||||
return getConnection().zunionstore(destKey, sets);
|
||||
} catch (Exception ex) {
|
||||
throw convertLettuceAccessException(ex);
|
||||
}
|
||||
return connection.invoke().just(RedisSortedSetAsyncCommands::zunionstore, destKey, sets);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -667,19 +372,7 @@ class LettuceZSetCommands implements RedisZSetCommands {
|
||||
|
||||
ZStoreArgs storeArgs = zStoreArgs(aggregate, weights);
|
||||
|
||||
try {
|
||||
if (isPipelined()) {
|
||||
pipeline(connection.newLettuceResult(getAsyncConnection().zinterstore(destKey, storeArgs, sets)));
|
||||
return null;
|
||||
}
|
||||
if (isQueueing()) {
|
||||
transaction(connection.newLettuceResult(getAsyncConnection().zinterstore(destKey, storeArgs, sets)));
|
||||
return null;
|
||||
}
|
||||
return getConnection().zinterstore(destKey, storeArgs, sets);
|
||||
} catch (Exception ex) {
|
||||
throw convertLettuceAccessException(ex);
|
||||
}
|
||||
return connection.invoke().just(RedisSortedSetAsyncCommands::zinterstore, destKey, storeArgs, sets);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -693,19 +386,7 @@ class LettuceZSetCommands implements RedisZSetCommands {
|
||||
Assert.notNull(sets, "Source sets must not be null!");
|
||||
Assert.noNullElements(sets, "Source sets must not contain null elements!");
|
||||
|
||||
try {
|
||||
if (isPipelined()) {
|
||||
pipeline(connection.newLettuceResult(getAsyncConnection().zinterstore(destKey, sets)));
|
||||
return null;
|
||||
}
|
||||
if (isQueueing()) {
|
||||
transaction(connection.newLettuceResult(getAsyncConnection().zinterstore(destKey, sets)));
|
||||
return null;
|
||||
}
|
||||
return getConnection().zinterstore(destKey, sets);
|
||||
} catch (Exception ex) {
|
||||
throw convertLettuceAccessException(ex);
|
||||
}
|
||||
return connection.invoke().just(RedisSortedSetAsyncCommands::zinterstore, destKey, sets);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -733,14 +414,15 @@ class LettuceZSetCommands implements RedisZSetCommands {
|
||||
@Override
|
||||
protected ScanIteration<Tuple> doScan(byte[] key, long cursorId, ScanOptions options) {
|
||||
|
||||
if (isQueueing() || isPipelined()) {
|
||||
if (connection.isQueueing() || connection.isPipelined()) {
|
||||
throw new UnsupportedOperationException("'ZSCAN' cannot be called in pipeline / transaction mode.");
|
||||
}
|
||||
|
||||
io.lettuce.core.ScanCursor scanCursor = connection.getScanCursor(cursorId);
|
||||
ScanArgs scanArgs = LettuceConverters.toScanArgs(options);
|
||||
|
||||
ScoredValueScanCursor<byte[]> scoredValueScanCursor = getConnection().zscan(key, scanCursor, scanArgs);
|
||||
ScoredValueScanCursor<byte[]> scoredValueScanCursor = connection.invoke()
|
||||
.just(RedisSortedSetAsyncCommands::zscan, key, scanCursor, scanArgs);
|
||||
String nextCursorId = scoredValueScanCursor.getCursor();
|
||||
|
||||
List<ScoredValue<byte[]>> result = scoredValueScanCursor.getValues();
|
||||
@@ -766,21 +448,7 @@ class LettuceZSetCommands implements RedisZSetCommands {
|
||||
|
||||
Assert.notNull(key, "Key must not be null!");
|
||||
|
||||
try {
|
||||
if (isPipelined()) {
|
||||
pipeline(connection.newLettuceResult(getAsyncConnection().zrangebyscore(key, min, max),
|
||||
LettuceConverters.bytesListToBytesSet()));
|
||||
return null;
|
||||
}
|
||||
if (isQueueing()) {
|
||||
transaction(connection.newLettuceResult(getAsyncConnection().zrangebyscore(key, min, max),
|
||||
LettuceConverters.bytesListToBytesSet()));
|
||||
return null;
|
||||
}
|
||||
return LettuceConverters.toBytesSet(getConnection().zrangebyscore(key, min, max));
|
||||
} catch (Exception ex) {
|
||||
throw convertLettuceAccessException(ex);
|
||||
}
|
||||
return connection.invoke().fromMany(RedisSortedSetAsyncCommands::zrangebyscore, key, min, max).toSet();
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -792,21 +460,8 @@ class LettuceZSetCommands implements RedisZSetCommands {
|
||||
|
||||
Assert.notNull(key, "Key must not be null!");
|
||||
|
||||
try {
|
||||
if (isPipelined()) {
|
||||
pipeline(connection.newLettuceResult(getAsyncConnection().zrangebyscore(key, min, max, offset, count),
|
||||
LettuceConverters.bytesListToBytesSet()));
|
||||
return null;
|
||||
}
|
||||
if (isQueueing()) {
|
||||
transaction(connection.newLettuceResult(getAsyncConnection().zrangebyscore(key, min, max, offset, count),
|
||||
LettuceConverters.bytesListToBytesSet()));
|
||||
return null;
|
||||
}
|
||||
return LettuceConverters.toBytesSet(getConnection().zrangebyscore(key, min, max, offset, count));
|
||||
} catch (Exception ex) {
|
||||
throw convertLettuceAccessException(ex);
|
||||
}
|
||||
return connection.invoke().fromMany(RedisSortedSetAsyncCommands::zrangebyscore, key, min, max, offset, count)
|
||||
.toSet();
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -820,38 +475,13 @@ class LettuceZSetCommands implements RedisZSetCommands {
|
||||
Assert.notNull(range, "Range for ZRANGEBYSCORE must not be null!");
|
||||
Assert.notNull(limit, "Limit must not be null!");
|
||||
|
||||
try {
|
||||
if (isPipelined()) {
|
||||
if (limit.isUnlimited()) {
|
||||
pipeline(
|
||||
connection.newLettuceResult(getAsyncConnection().zrangebyscore(key, LettuceConverters.toRange(range)),
|
||||
LettuceConverters.bytesListToBytesSet()));
|
||||
} else {
|
||||
pipeline(connection.newLettuceResult(getAsyncConnection().zrangebyscore(key, LettuceConverters.toRange(range),
|
||||
LettuceConverters.toLimit(limit)), LettuceConverters.bytesListToBytesSet()));
|
||||
}
|
||||
return null;
|
||||
}
|
||||
if (isQueueing()) {
|
||||
if (limit.isUnlimited()) {
|
||||
transaction(
|
||||
connection.newLettuceResult(getAsyncConnection().zrangebyscore(key, LettuceConverters.toRange(range)),
|
||||
LettuceConverters.bytesListToBytesSet()));
|
||||
} else {
|
||||
transaction(
|
||||
connection.newLettuceResult(getAsyncConnection().zrangebyscore(key, LettuceConverters.toRange(range),
|
||||
LettuceConverters.toLimit(limit)), LettuceConverters.bytesListToBytesSet()));
|
||||
}
|
||||
return null;
|
||||
}
|
||||
if (limit.isUnlimited()) {
|
||||
return LettuceConverters.toBytesSet(getConnection().zrangebyscore(key, LettuceConverters.toRange(range)));
|
||||
}
|
||||
return LettuceConverters.toBytesSet(
|
||||
getConnection().zrangebyscore(key, LettuceConverters.toRange(range), LettuceConverters.toLimit(limit)));
|
||||
} catch (Exception ex) {
|
||||
throw convertLettuceAccessException(ex);
|
||||
if (limit.isUnlimited()) {
|
||||
return connection.invoke()
|
||||
.fromMany(RedisSortedSetAsyncCommands::zrangebyscore, key, LettuceConverters.<Number> toRange(range)).toSet();
|
||||
}
|
||||
|
||||
return connection.invoke().fromMany(RedisSortedSetAsyncCommands::zrangebyscore, key,
|
||||
LettuceConverters.<Number> toRange(range), LettuceConverters.toLimit(limit)).toSet();
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -865,42 +495,14 @@ class LettuceZSetCommands implements RedisZSetCommands {
|
||||
Assert.notNull(range, "Range for ZRANGEBYLEX must not be null!");
|
||||
Assert.notNull(limit, "Limit must not be null!");
|
||||
|
||||
try {
|
||||
if (isPipelined()) {
|
||||
if (limit.isUnlimited()) {
|
||||
pipeline(
|
||||
connection.newLettuceResult(getAsyncConnection().zrangebylex(key, LettuceConverters.toRange(range, true)),
|
||||
LettuceConverters.bytesListToBytesSet()));
|
||||
} else {
|
||||
pipeline(
|
||||
connection.newLettuceResult(getAsyncConnection().zrangebylex(key, LettuceConverters.toRange(range, true),
|
||||
LettuceConverters.toLimit(limit)), LettuceConverters.bytesListToBytesSet()));
|
||||
}
|
||||
return null;
|
||||
}
|
||||
if (isQueueing()) {
|
||||
if (limit.isUnlimited()) {
|
||||
transaction(
|
||||
connection.newLettuceResult(getAsyncConnection().zrangebylex(key, LettuceConverters.toRange(range, true)),
|
||||
LettuceConverters.bytesListToBytesSet()));
|
||||
} else {
|
||||
transaction(
|
||||
connection.newLettuceResult(getAsyncConnection().zrangebylex(key, LettuceConverters.toRange(range, true),
|
||||
LettuceConverters.toLimit(limit)), LettuceConverters.bytesListToBytesSet()));
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
if (limit.isUnlimited()) {
|
||||
return LettuceConverters.bytesListToBytesSet()
|
||||
.convert(getConnection().zrangebylex(key, LettuceConverters.toRange(range, true)));
|
||||
}
|
||||
return LettuceConverters.bytesListToBytesSet().convert(
|
||||
getConnection().zrangebylex(key, LettuceConverters.toRange(range, true), LettuceConverters.toLimit(limit)));
|
||||
|
||||
} catch (Exception ex) {
|
||||
throw convertLettuceAccessException(ex);
|
||||
if (limit.isUnlimited()) {
|
||||
return connection.invoke()
|
||||
.fromMany(RedisSortedSetAsyncCommands::zrangebylex, key, LettuceConverters.<byte[]> toRange(range, true))
|
||||
.toSet();
|
||||
}
|
||||
|
||||
return connection.invoke().fromMany(RedisSortedSetAsyncCommands::zrangebylex, key,
|
||||
LettuceConverters.<byte[]> toRange(range, true), LettuceConverters.toLimit(limit)).toSet();
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -914,72 +516,20 @@ class LettuceZSetCommands implements RedisZSetCommands {
|
||||
Assert.notNull(range, "Range for ZREVRANGEBYLEX must not be null!");
|
||||
Assert.notNull(limit, "Limit must not be null!");
|
||||
|
||||
try {
|
||||
if (isPipelined()) {
|
||||
if (limit.isUnlimited()) {
|
||||
pipeline(connection.newLettuceResult(
|
||||
getAsyncConnection().zrevrangebylex(key, LettuceConverters.toRange(range, true)),
|
||||
LettuceConverters.bytesListToBytesSet()));
|
||||
} else {
|
||||
pipeline(connection.newLettuceResult(getAsyncConnection().zrevrangebylex(key,
|
||||
LettuceConverters.toRange(range, true), LettuceConverters.toLimit(limit)),
|
||||
LettuceConverters.bytesListToBytesSet()));
|
||||
}
|
||||
return null;
|
||||
}
|
||||
if (isQueueing()) {
|
||||
if (limit.isUnlimited()) {
|
||||
transaction(connection.newLettuceResult(
|
||||
getAsyncConnection().zrevrangebylex(key, LettuceConverters.toRange(range, true)),
|
||||
LettuceConverters.bytesListToBytesSet()));
|
||||
} else {
|
||||
transaction(connection.newLettuceResult(getAsyncConnection().zrevrangebylex(key,
|
||||
LettuceConverters.toRange(range, true), LettuceConverters.toLimit(limit)),
|
||||
LettuceConverters.bytesListToBytesSet()));
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
if (limit.isUnlimited()) {
|
||||
return LettuceConverters.bytesListToBytesSet()
|
||||
.convert(getConnection().zrevrangebylex(key, LettuceConverters.toRange(range, true)));
|
||||
}
|
||||
return LettuceConverters.bytesListToBytesSet().convert(getConnection().zrevrangebylex(key,
|
||||
LettuceConverters.toRange(range, true), LettuceConverters.toLimit(limit)));
|
||||
|
||||
} catch (Exception ex) {
|
||||
throw convertLettuceAccessException(ex);
|
||||
if (limit.isUnlimited()) {
|
||||
return connection.invoke()
|
||||
.fromMany(RedisSortedSetAsyncCommands::zrevrangebylex, key, LettuceConverters.<byte[]> toRange(range, true))
|
||||
.toSet();
|
||||
}
|
||||
}
|
||||
|
||||
private boolean isPipelined() {
|
||||
return connection.isPipelined();
|
||||
}
|
||||
|
||||
private boolean isQueueing() {
|
||||
return connection.isQueueing();
|
||||
}
|
||||
|
||||
private void pipeline(LettuceResult result) {
|
||||
connection.pipeline(result);
|
||||
}
|
||||
|
||||
private void transaction(LettuceResult result) {
|
||||
connection.transaction(result);
|
||||
}
|
||||
|
||||
RedisClusterAsyncCommands<byte[], byte[]> getAsyncConnection() {
|
||||
return connection.getAsyncConnection();
|
||||
return connection.invoke().fromMany(RedisSortedSetAsyncCommands::zrevrangebylex, key,
|
||||
LettuceConverters.<byte[]> toRange(range, true), LettuceConverters.toLimit(limit)).toSet();
|
||||
}
|
||||
|
||||
public RedisClusterCommands<byte[], byte[]> getConnection() {
|
||||
return connection.getConnection();
|
||||
}
|
||||
|
||||
private DataAccessException convertLettuceAccessException(Exception ex) {
|
||||
return connection.convertLettuceAccessException(ex);
|
||||
}
|
||||
|
||||
private static ZStoreArgs zStoreArgs(@Nullable Aggregate aggregate, Weights weights) {
|
||||
|
||||
ZStoreArgs args = new ZStoreArgs();
|
||||
|
||||
Reference in New Issue
Block a user