Improvement - RScript read-only cached scripts should be executed on slaves (supported only by Redis 7.0+)

pull/4104/head
Nikita Koksharov 3 years ago
parent 0b4c94c269
commit 905c047e60

@ -200,8 +200,20 @@ public class RedissonScript implements RScript {
public <R> RFuture<R> evalShaAsync(String key, Mode mode, String shaDigest, ReturnType returnType, public <R> RFuture<R> evalShaAsync(String key, Mode mode, String shaDigest, ReturnType returnType,
List<Object> keys, Object... values) { List<Object> keys, Object... values) {
RedisCommand command = new RedisCommand(returnType.getCommand(), "EVALSHA"); RedisCommand command = new RedisCommand(returnType.getCommand(), "EVALSHA");
if (mode == Mode.READ_ONLY) { if (mode == Mode.READ_ONLY && commandExecutor.isEvalShaROSupported()) {
return commandExecutor.evalReadAsync(key, codec, command, shaDigest, keys, encode(Arrays.asList(values), codec).toArray()); RedisCommand cmd = new RedisCommand(returnType.getCommand(), "EVALSHA_RO");
RFuture<R> f = commandExecutor.evalReadAsync(key, codec, cmd, shaDigest, keys, encode(Arrays.asList(values), codec).toArray());
CompletableFuture<R> result = new CompletableFuture<>();
f.whenComplete((r, e) -> {
if (e != null) {
if (e.getMessage().startsWith("ERR unknown command")) {
commandExecutor.setEvalShaROSupported(false);
RFuture<R> s = evalShaAsync(key, mode, shaDigest, returnType, keys, values);
commandExecutor.transfer(s.toCompletableFuture(), result);
}
}
});
return new CompletableFutureWrapper<>(result);
} }
return commandExecutor.evalWriteAsync(key, codec, command, shaDigest, keys, encode(Arrays.asList(values), codec).toArray()); return commandExecutor.evalWriteAsync(key, codec, command, shaDigest, keys, encode(Arrays.asList(values), codec).toArray());
} }

@ -132,4 +132,8 @@ public interface CommandAsyncExecutor {
<T, R> RFuture<R> writeBatchedAsync(Codec codec, RedisCommand<T> command, SlotCallback<T, R> callback, String... keys); <T, R> RFuture<R> writeBatchedAsync(Codec codec, RedisCommand<T> command, SlotCallback<T, R> callback, String... keys);
boolean isEvalShaROSupported();
void setEvalShaROSupported(boolean value);
} }

@ -498,8 +498,16 @@ public class CommandAsyncService implements CommandAsyncExecutor {
return result.toArray(); return result.toArray();
} }
private AtomicBoolean evalShaROSupported = new AtomicBoolean(true); private final AtomicBoolean evalShaROSupported = new AtomicBoolean(true);
public boolean isEvalShaROSupported() {
return evalShaROSupported.get();
}
public void setEvalShaROSupported(boolean value) {
this.evalShaROSupported.set(value);
}
private <T, R> RFuture<R> evalAsync(NodeSource nodeSource, boolean readOnlyMode, Codec codec, RedisCommand<T> evalCommandType, private <T, R> RFuture<R> evalAsync(NodeSource nodeSource, boolean readOnlyMode, Codec codec, RedisCommand<T> evalCommandType,
String script, List<Object> keys, boolean noRetry, Object... params) { String script, List<Object> keys, boolean noRetry, Object... params) {
if (isEvalCacheActive() && evalCommandType.getName().equals("EVAL")) { if (isEvalCacheActive() && evalCommandType.getName().equals("EVAL")) {

Loading…
Cancel
Save