Add functionality to recalculate slots when receiving MOVED response from node.

Add test to check for ASK responses (implementation missing)
This commit is contained in:
Marcos Nils
2014-01-02 20:52:17 -03:00
parent b2d22e2060
commit 1b26815799
5 changed files with 94 additions and 24 deletions

View File

@@ -6,6 +6,7 @@ import redis.clients.jedis.exceptions.JedisMovedDataException;
public abstract class JedisClusterCommand<T> {
private JedisClusterConnectionHandler connectionHandler;
private boolean asking = false;
public JedisClusterCommand(JedisClusterConnectionHandler connectionHandler) {
this.connectionHandler = connectionHandler;
@@ -17,10 +18,10 @@ public abstract class JedisClusterCommand<T> {
try {
return execute();
} catch (JedisMovedDataException jme) {
//TODO: Do Retry here
this.connectionHandler.assignSlotToNode(jme.getSlot(), jme.getTargetNode());
return execute();
} catch (JedisAskDataException jae) {
//TODO: Do ASK here
throw jae;
}
return null;
}
}

View File

@@ -64,4 +64,9 @@ public abstract class JedisClusterConnectionHandler {
String[] arrayHostAndPort = stringHostAndPort.split(":");
return new HostAndPort(arrayHostAndPort[0], Integer.valueOf(arrayHostAndPort[1]));
}
public void assignSlotToNode(int slot, HostAndPort targetNode) {
JedisPool targetPool = nodes.get(targetNode.getHost() + targetNode.getPort());
slots.put(slot, targetPool);
}
}

View File

@@ -80,7 +80,9 @@ public final class Protocol {
//TODO: I'm not sure if this is the best way to do this.
//Maybe Read only first 5 bytes instead?
if (message.contains(MOVED_RESPONSE)) {
throw new JedisMovedDataException(message);
String[] movedInfo = message.split(" ");
String[] targetHostAndPort = movedInfo[2].split(":");
throw new JedisMovedDataException(message, new HostAndPort(targetHostAndPort[0], Integer.valueOf(targetHostAndPort[1])), Integer.valueOf(movedInfo[1]));
} else if (message.contains(ASK_RESPONSE)) {
throw new JedisAskDataException(message);
}

View File

@@ -1,17 +1,37 @@
package redis.clients.jedis.exceptions;
import redis.clients.jedis.HostAndPort;
public class JedisMovedDataException extends JedisDataException {
private static final long serialVersionUID = 3878126572474819403L;
private HostAndPort targetNode;
private int slot;
public JedisMovedDataException(String message) {
super(message);
public JedisMovedDataException(String message, HostAndPort targetNode, int slot) {
super(message);
this.targetNode = targetNode;
this.slot = slot;
}
public JedisMovedDataException(Throwable cause) {
public JedisMovedDataException(Throwable cause, HostAndPort targetNode, int slot) {
super(cause);
this.targetNode = targetNode;
this.slot = slot;
}
public JedisMovedDataException(String message, Throwable cause) {
public JedisMovedDataException(String message, Throwable cause, HostAndPort targetNode, int slot) {
super(message, cause);
this.targetNode = targetNode;
this.slot = slot;
}
public HostAndPort getTargetNode() {
return targetNode;
}
public int getSlot() {
return slot;
}
}