package com.lambdaworks.redis.cluster; import com.lambdaworks.redis.RedisChannelWriter; import com.lambdaworks.redis.protocol.CommandArgs; import com.lambdaworks.redis.protocol.CommandKeyword; import com.lambdaworks.redis.protocol.CommandWrapper; import com.lambdaworks.redis.protocol.ProtocolKeyword; import com.lambdaworks.redis.protocol.RedisCommand; import io.netty.buffer.ByteBuf; /** * @author Mark Paluch * @since 3.0 */ class ClusterCommand<K, V, T> extends CommandWrapper<K, V, T> implements RedisCommand<K, V, T> { private int redirections; private final int maxRedirections; private final RedisChannelWriter<K, V> retry; private boolean completed; /** * * @param command * @param retry * @param maxRedirections */ ClusterCommand(RedisCommand<K, V, T> command, RedisChannelWriter<K, V> retry, int maxRedirections) { super(command); this.retry = retry; this.maxRedirections = maxRedirections; } @Override public void complete() { if (isMoved() || isAsk()) { boolean retryCommand = maxRedirections > redirections; redirections++; if(retryCommand) { try { retry.write(this); } catch (Exception e) { completeExceptionally(e); } return; } } super.complete(); completed = true; } public boolean isMoved() { if (command.getOutput() != null && command.getOutput().getError() != null && command.getOutput().getError().startsWith(CommandKeyword.MOVED.name())) { return true; } return false; } public boolean isAsk() { if (getError() != null && getError().startsWith(CommandKeyword.ASK.name())) { return true; } return false; } @Override public CommandArgs<K, V> getArgs() { return command.getArgs(); } @Override public void encode(ByteBuf buf) { command.encode(buf); } @Override public boolean completeExceptionally(Throwable ex) { boolean result = command.completeExceptionally(ex); completed = true; return result; } @Override public ProtocolKeyword getType() { return command.getType(); } public boolean isCompleted() { return completed; } @Override public boolean isDone() { return isCompleted(); } public String getError() { if (command.getOutput() != null) { return command.getOutput().getError(); } return null; } @Override public String toString() { final StringBuilder sb = new StringBuilder(); sb.append(getClass().getSimpleName()); sb.append(" [command=").append(command); sb.append(", redirections=").append(redirections); sb.append(", maxRedirections=").append(maxRedirections); sb.append(']'); return sb.toString(); } }