Fixed - SET command should be an idempotent operation #4250

pull/4272/head
Nikita Koksharov 3 years ago
parent c1a7fb84ca
commit 88999986e4

@ -107,6 +107,11 @@ public class RedisCommand<R> {
return convertor;
}
public boolean isNoRetry() {
return RedisCommands.NO_RETRY.contains(getName())
|| RedisCommands.NO_RETRY_COMMANDS.contains(this);
}
public boolean isBlockingCommand() {
return RedisCommands.BLOCKING_COMMAND_NAMES.contains(getName())
|| RedisCommands.BLOCKING_COMMANDS.contains(this);

@ -668,11 +668,12 @@ public interface RedisCommands {
RedisStrictCommand<Map<String, String>> INFO_CLUSTER = new RedisStrictCommand<Map<String, String>>("INFO", "CLUSTER", new StringMapDataDecoder());
RedisStrictCommand<Map<String, String>> INFO_KEYSPACE = new RedisStrictCommand<Map<String, String>>("INFO", "KEYSPACE", new StringMapDataDecoder());
Set<RedisCommand> NO_RETRY_COMMANDS = new HashSet<>(Arrays.asList(SET_BOOLEAN));
Set<String> NO_RETRY = new HashSet<>(
Arrays.asList(RPOPLPUSH.getName(), LPOP.getName(), RPOP.getName(), LPUSH.getName(), RPUSH.getName(),
LPUSHX.getName(), RPUSHX.getName(), GEOADD.getName(), XADD.getName(), APPEND.getName(),
DECR.getName(), "DECRBY", INCR.getName(), INCRBY.getName(), ZINCRBY.getName(),
"HINCRBYFLOAT", "HINCRBY", "INCRBYFLOAT", SET_BOOLEAN.getName(), SETNX.getName(),
MSETNX.getName(), HSETNX.getName()));
"HINCRBYFLOAT", "HINCRBY", "INCRBYFLOAT", SETNX.getName(), MSETNX.getName(), HSETNX.getName()));
}

@ -336,7 +336,9 @@ public class RedisExecutor<V, R> {
attemptPromise.completeExceptionally(
new RedisResponseTimeoutException("Redis server response timeout (" + timeoutAmount + " ms) occured"
+ " after " + attempt + " retry attempts. Increase nettyThreads and/or timeout settings. Try to define pingConnectionInterval setting. Command: "
+ " after " + attempt + " retry attempts,"
+ " is non-idempotent command: " + (command != null && command.isNoRetry())
+ ". Increase nettyThreads and/or timeout settings. Try to define pingConnectionInterval setting. Command: "
+ LogHelper.toString(command, params) + ", channel: " + connection.getChannel()));
};
@ -346,7 +348,7 @@ public class RedisExecutor<V, R> {
protected boolean isResendAllowed(int attempt, int attempts) {
return attempt < attempts
&& !noRetry
&& (command == null || (!command.isBlockingCommand() && !RedisCommands.NO_RETRY.contains(command.getName())));
&& (command == null || (!command.isBlockingCommand() && !command.isNoRetry()));
}
private void handleBlockingOperations(CompletableFuture<R> attemptPromise, RedisConnection connection, Long popTimeout) {

Loading…
Cancel
Save