From 68ee4e49d061ad66352e146612c2ab9bdc0fd566 Mon Sep 17 00:00:00 2001 From: Jungtaek Lim Date: Mon, 17 Feb 2014 13:37:06 +0900 Subject: [PATCH 01/16] Set dependency to Response when multi in pipeline and build dependency first if Response's dependency found and not built * there's some dependency with exec response and command responses within multi * if command responses's get() called before exec response's build(), it calls exec response's build() first * unit test included --- .../java/redis/clients/jedis/Pipeline.java | 7 ++++ .../java/redis/clients/jedis/Response.java | 34 ++++++++++++++----- .../clients/jedis/tests/PipeliningTest.java | 21 ++++++++++++ 3 files changed, 54 insertions(+), 8 deletions(-) diff --git a/src/main/java/redis/clients/jedis/Pipeline.java b/src/main/java/redis/clients/jedis/Pipeline.java index 97f856b..2687f84 100755 --- a/src/main/java/redis/clients/jedis/Pipeline.java +++ b/src/main/java/redis/clients/jedis/Pipeline.java @@ -31,6 +31,12 @@ public class Pipeline extends MultiKeyPipelineBase { return values; } + public void setResponseDependency(Response dependency) { + for (Response response : responses) { + response.setDependency(dependency); + } + } + public void addResponse(Response response) { responses.add(response); } @@ -106,6 +112,7 @@ public class Pipeline extends MultiKeyPipelineBase { public Response> exec() { client.exec(); Response> response = super.getResponse(currentMulti); + currentMulti.setResponseDependency(response); currentMulti = null; return response; } diff --git a/src/main/java/redis/clients/jedis/Response.java b/src/main/java/redis/clients/jedis/Response.java index b17f314..955277a 100644 --- a/src/main/java/redis/clients/jedis/Response.java +++ b/src/main/java/redis/clients/jedis/Response.java @@ -8,6 +8,8 @@ public class Response { private boolean set = false; private Builder builder; private Object data; + private Response dependency = null; + private boolean requestDependencyBuild = false; public Response(Builder b) { this.builder = b; @@ -19,23 +21,39 @@ public class Response { } public T get() { + // if response has dependency response and dependency is not built, + // build it first and no more!! + if (!requestDependencyBuild && dependency != null && dependency.set + && !dependency.built) { + requestDependencyBuild = true; + dependency.build(); + } if (!set) { throw new JedisDataException( "Please close pipeline or multi block before calling this method."); } if (!built) { - if (data != null) { - if (data instanceof JedisDataException) { - throw new JedisDataException((JedisDataException) data); - } - response = builder.build(data); - } - this.data = null; - built = true; + build(); } return response; } + public void setDependency(Response dependency) { + this.dependency = dependency; + this.requestDependencyBuild = false; + } + + private void build() { + if (data != null) { + if (data instanceof JedisDataException) { + throw new JedisDataException((JedisDataException) data); + } + response = builder.build(data); + } + data = null; + built = true; + } + public String toString() { return "Response " + builder.toString(); } diff --git a/src/test/java/redis/clients/jedis/tests/PipeliningTest.java b/src/test/java/redis/clients/jedis/tests/PipeliningTest.java index aed67dc..d3cddd0 100755 --- a/src/test/java/redis/clients/jedis/tests/PipeliningTest.java +++ b/src/test/java/redis/clients/jedis/tests/PipeliningTest.java @@ -251,6 +251,27 @@ public class PipeliningTest extends Assert { } + @Test + public void multiWithSync() { + jedis.set("foo", "314"); + jedis.set("bar", "foo"); + jedis.set("hello", "world"); + Pipeline p = jedis.pipelined(); + Response r1 = p.get("bar"); + p.multi(); + Response r2 = p.get("foo"); + p.exec(); + Response r3 = p.get("hello"); + p.sync(); + + // before multi + assertEquals("foo", r1.get()); + // It should be readable whether exec's response was built or not + assertEquals("314", r2.get()); + // after multi + assertEquals("world", r3.get()); + } + @Test public void testDiscardInPipeline() { Pipeline pipeline = jedis.pipelined(); From e4de67048eac13e67f3fa683d7360a400d882f1f Mon Sep 17 00:00:00 2001 From: Marcos Nils Date: Tue, 18 Feb 2014 21:59:53 -0300 Subject: [PATCH 02/16] Make JedisCluster multihread by improving connection handling --- .../redis/clients/jedis/JedisCluster.java | 488 +++++++++--------- .../clients/jedis/JedisClusterCommand.java | 13 +- .../jedis/JedisClusterConnectionHandler.java | 7 + .../JedisSlotBasedConnectionHandler.java | 19 +- 4 files changed, 262 insertions(+), 265 deletions(-) diff --git a/src/main/java/redis/clients/jedis/JedisCluster.java b/src/main/java/redis/clients/jedis/JedisCluster.java index bec2574..1f645ea 100644 --- a/src/main/java/redis/clients/jedis/JedisCluster.java +++ b/src/main/java/redis/clients/jedis/JedisCluster.java @@ -38,8 +38,8 @@ public class JedisCluster implements JedisCommands, BasicCommands { return new JedisClusterCommand(connectionHandler, timeout, maxRedirections) { @Override - public String execute() { - return connectionHandler.getConnection().set(key, value); + public String execute(Jedis connection) { + return connection.set(key, value); } }.run(key); } @@ -49,8 +49,8 @@ public class JedisCluster implements JedisCommands, BasicCommands { return new JedisClusterCommand(connectionHandler, timeout, maxRedirections) { @Override - public String execute() { - return connectionHandler.getConnection().get(key); + public String execute(Jedis connection) { + return connection.get(key); } }.run(key); } @@ -60,8 +60,8 @@ public class JedisCluster implements JedisCommands, BasicCommands { return new JedisClusterCommand(connectionHandler, timeout, maxRedirections) { @Override - public Boolean execute() { - return connectionHandler.getConnection().exists(key); + public Boolean execute(Jedis connection) { + return connection.exists(key); } }.run(key); } @@ -71,8 +71,8 @@ public class JedisCluster implements JedisCommands, BasicCommands { return new JedisClusterCommand(connectionHandler, timeout, maxRedirections) { @Override - public Long execute() { - return connectionHandler.getConnection().persist(key); + public Long execute(Jedis connection) { + return connection.persist(key); } }.run(key); } @@ -82,8 +82,8 @@ public class JedisCluster implements JedisCommands, BasicCommands { return new JedisClusterCommand(connectionHandler, timeout, maxRedirections) { @Override - public String execute() { - return connectionHandler.getConnection().type(key); + public String execute(Jedis connection) { + return connection.type(key); } }.run(key); } @@ -93,8 +93,8 @@ public class JedisCluster implements JedisCommands, BasicCommands { return new JedisClusterCommand(connectionHandler, timeout, maxRedirections) { @Override - public Long execute() { - return connectionHandler.getConnection().expire(key, seconds); + public Long execute(Jedis connection) { + return connection.expire(key, seconds); } }.run(key); } @@ -104,8 +104,8 @@ public class JedisCluster implements JedisCommands, BasicCommands { return new JedisClusterCommand(connectionHandler, timeout, maxRedirections) { @Override - public Long execute() { - return connectionHandler.getConnection() + public Long execute(Jedis connection) { + return connection .expireAt(key, unixTime); } }.run(key); @@ -116,8 +116,8 @@ public class JedisCluster implements JedisCommands, BasicCommands { return new JedisClusterCommand(connectionHandler, timeout, maxRedirections) { @Override - public Long execute() { - return connectionHandler.getConnection().ttl(key); + public Long execute(Jedis connection) { + return connection.ttl(key); } }.run(key); } @@ -128,8 +128,8 @@ public class JedisCluster implements JedisCommands, BasicCommands { return new JedisClusterCommand(connectionHandler, timeout, maxRedirections) { @Override - public Boolean execute() { - return connectionHandler.getConnection().setbit(key, offset, + public Boolean execute(Jedis connection) { + return connection.setbit(key, offset, value); } }.run(key); @@ -141,8 +141,8 @@ public class JedisCluster implements JedisCommands, BasicCommands { return new JedisClusterCommand(connectionHandler, timeout, maxRedirections) { @Override - public Boolean execute() { - return connectionHandler.getConnection().setbit(key, offset, + public Boolean execute(Jedis connection) { + return connection.setbit(key, offset, value); } }.run(key); @@ -153,8 +153,8 @@ public class JedisCluster implements JedisCommands, BasicCommands { return new JedisClusterCommand(connectionHandler, timeout, maxRedirections) { @Override - public Boolean execute() { - return connectionHandler.getConnection().getbit(key, offset); + public Boolean execute(Jedis connection) { + return connection.getbit(key, offset); } }.run(key); } @@ -164,8 +164,8 @@ public class JedisCluster implements JedisCommands, BasicCommands { return new JedisClusterCommand(connectionHandler, timeout, maxRedirections) { @Override - public Long execute() { - return connectionHandler.getConnection().setrange(key, offset, + public Long execute(Jedis connection) { + return connection.setrange(key, offset, value); } }.run(key); @@ -177,8 +177,8 @@ public class JedisCluster implements JedisCommands, BasicCommands { return new JedisClusterCommand(connectionHandler, timeout, maxRedirections) { @Override - public String execute() { - return connectionHandler.getConnection().getrange(key, + public String execute(Jedis connection) { + return connection.getrange(key, startOffset, endOffset); } }.run(key); @@ -189,8 +189,8 @@ public class JedisCluster implements JedisCommands, BasicCommands { return new JedisClusterCommand(connectionHandler, timeout, maxRedirections) { @Override - public String execute() { - return connectionHandler.getConnection().getSet(key, value); + public String execute(Jedis connection) { + return connection.getSet(key, value); } }.run(key); } @@ -200,8 +200,8 @@ public class JedisCluster implements JedisCommands, BasicCommands { return new JedisClusterCommand(connectionHandler, timeout, maxRedirections) { @Override - public Long execute() { - return connectionHandler.getConnection().setnx(key, value); + public Long execute(Jedis connection) { + return connection.setnx(key, value); } }.run(key); } @@ -211,8 +211,8 @@ public class JedisCluster implements JedisCommands, BasicCommands { return new JedisClusterCommand(connectionHandler, timeout, maxRedirections) { @Override - public String execute() { - return connectionHandler.getConnection().setex(key, seconds, + public String execute(Jedis connection) { + return connection.setex(key, seconds, value); } }.run(key); @@ -223,8 +223,8 @@ public class JedisCluster implements JedisCommands, BasicCommands { return new JedisClusterCommand(connectionHandler, timeout, maxRedirections) { @Override - public Long execute() { - return connectionHandler.getConnection().decrBy(key, integer); + public Long execute(Jedis connection) { + return connection.decrBy(key, integer); } }.run(key); } @@ -234,8 +234,8 @@ public class JedisCluster implements JedisCommands, BasicCommands { return new JedisClusterCommand(connectionHandler, timeout, maxRedirections) { @Override - public Long execute() { - return connectionHandler.getConnection().decr(key); + public Long execute(Jedis connection) { + return connection.decr(key); } }.run(key); } @@ -245,8 +245,8 @@ public class JedisCluster implements JedisCommands, BasicCommands { return new JedisClusterCommand(connectionHandler, timeout, maxRedirections) { @Override - public Long execute() { - return connectionHandler.getConnection().incrBy(key, integer); + public Long execute(Jedis connection) { + return connection.incrBy(key, integer); } }.run(key); } @@ -256,8 +256,8 @@ public class JedisCluster implements JedisCommands, BasicCommands { return new JedisClusterCommand(connectionHandler, timeout, maxRedirections) { @Override - public Long execute() { - return connectionHandler.getConnection().incr(key); + public Long execute(Jedis connection) { + return connection.incr(key); } }.run(key); } @@ -267,8 +267,8 @@ public class JedisCluster implements JedisCommands, BasicCommands { return new JedisClusterCommand(connectionHandler, timeout, maxRedirections) { @Override - public Long execute() { - return connectionHandler.getConnection().append(key, value); + public Long execute(Jedis connection) { + return connection.append(key, value); } }.run(key); } @@ -278,8 +278,8 @@ public class JedisCluster implements JedisCommands, BasicCommands { return new JedisClusterCommand(connectionHandler, timeout, maxRedirections) { @Override - public String execute() { - return connectionHandler.getConnection() + public String execute(Jedis connection) { + return connection .substr(key, start, end); } }.run(key); @@ -290,8 +290,8 @@ public class JedisCluster implements JedisCommands, BasicCommands { return new JedisClusterCommand(connectionHandler, timeout, maxRedirections) { @Override - public Long execute() { - return connectionHandler.getConnection() + public Long execute(Jedis connection) { + return connection .hset(key, field, value); } }.run(key); @@ -302,8 +302,8 @@ public class JedisCluster implements JedisCommands, BasicCommands { return new JedisClusterCommand(connectionHandler, timeout, maxRedirections) { @Override - public String execute() { - return connectionHandler.getConnection().hget(key, field); + public String execute(Jedis connection) { + return connection.hget(key, field); } }.run(key); } @@ -313,8 +313,8 @@ public class JedisCluster implements JedisCommands, BasicCommands { return new JedisClusterCommand(connectionHandler, timeout, maxRedirections) { @Override - public Long execute() { - return connectionHandler.getConnection().hsetnx(key, field, + public Long execute(Jedis connection) { + return connection.hsetnx(key, field, value); } }.run(key); @@ -325,8 +325,8 @@ public class JedisCluster implements JedisCommands, BasicCommands { return new JedisClusterCommand(connectionHandler, timeout, maxRedirections) { @Override - public String execute() { - return connectionHandler.getConnection().hmset(key, hash); + public String execute(Jedis connection) { + return connection.hmset(key, hash); } }.run(key); } @@ -336,8 +336,8 @@ public class JedisCluster implements JedisCommands, BasicCommands { return new JedisClusterCommand>(connectionHandler, timeout, maxRedirections) { @Override - public List execute() { - return connectionHandler.getConnection().hmget(key, fields); + public List execute(Jedis connection) { + return connection.hmget(key, fields); } }.run(key); } @@ -347,8 +347,8 @@ public class JedisCluster implements JedisCommands, BasicCommands { return new JedisClusterCommand(connectionHandler, timeout, maxRedirections) { @Override - public Long execute() { - return connectionHandler.getConnection().hincrBy(key, field, + public Long execute(Jedis connection) { + return connection.hincrBy(key, field, value); } }.run(key); @@ -359,8 +359,8 @@ public class JedisCluster implements JedisCommands, BasicCommands { return new JedisClusterCommand(connectionHandler, timeout, maxRedirections) { @Override - public Boolean execute() { - return connectionHandler.getConnection().hexists(key, field); + public Boolean execute(Jedis connection) { + return connection.hexists(key, field); } }.run(key); } @@ -370,8 +370,8 @@ public class JedisCluster implements JedisCommands, BasicCommands { return new JedisClusterCommand(connectionHandler, timeout, maxRedirections) { @Override - public Long execute() { - return connectionHandler.getConnection().hdel(key, field); + public Long execute(Jedis connection) { + return connection.hdel(key, field); } }.run(key); } @@ -381,8 +381,8 @@ public class JedisCluster implements JedisCommands, BasicCommands { return new JedisClusterCommand(connectionHandler, timeout, maxRedirections) { @Override - public Long execute() { - return connectionHandler.getConnection().hdel(key); + public Long execute(Jedis connection) { + return connection.hdel(key); } }.run(key); } @@ -392,8 +392,8 @@ public class JedisCluster implements JedisCommands, BasicCommands { return new JedisClusterCommand>(connectionHandler, timeout, maxRedirections) { @Override - public Set execute() { - return connectionHandler.getConnection().hkeys(key); + public Set execute(Jedis connection) { + return connection.hkeys(key); } }.run(key); } @@ -403,8 +403,8 @@ public class JedisCluster implements JedisCommands, BasicCommands { return new JedisClusterCommand>(connectionHandler, timeout, maxRedirections) { @Override - public List execute() { - return connectionHandler.getConnection().hvals(key); + public List execute(Jedis connection) { + return connection.hvals(key); } }.run(key); } @@ -414,8 +414,8 @@ public class JedisCluster implements JedisCommands, BasicCommands { return new JedisClusterCommand>(connectionHandler, timeout, maxRedirections) { @Override - public Map execute() { - return connectionHandler.getConnection().hgetAll(key); + public Map execute(Jedis connection) { + return connection.hgetAll(key); } }.run(key); } @@ -425,8 +425,8 @@ public class JedisCluster implements JedisCommands, BasicCommands { return new JedisClusterCommand(connectionHandler, timeout, maxRedirections) { @Override - public Long execute() { - return connectionHandler.getConnection().rpush(key, string); + public Long execute(Jedis connection) { + return connection.rpush(key, string); } }.run(key); } @@ -436,8 +436,8 @@ public class JedisCluster implements JedisCommands, BasicCommands { return new JedisClusterCommand(connectionHandler, timeout, maxRedirections) { @Override - public Long execute() { - return connectionHandler.getConnection().lpush(key, string); + public Long execute(Jedis connection) { + return connection.lpush(key, string); } }.run(key); } @@ -447,8 +447,8 @@ public class JedisCluster implements JedisCommands, BasicCommands { return new JedisClusterCommand(connectionHandler, timeout, maxRedirections) { @Override - public Long execute() { - return connectionHandler.getConnection().llen(key); + public Long execute(Jedis connection) { + return connection.llen(key); } }.run(key); } @@ -459,8 +459,8 @@ public class JedisCluster implements JedisCommands, BasicCommands { return new JedisClusterCommand>(connectionHandler, timeout, maxRedirections) { @Override - public List execute() { - return connectionHandler.getConnection() + public List execute(Jedis connection) { + return connection .lrange(key, start, end); } }.run(key); @@ -471,8 +471,8 @@ public class JedisCluster implements JedisCommands, BasicCommands { return new JedisClusterCommand(connectionHandler, timeout, maxRedirections) { @Override - public String execute() { - return connectionHandler.getConnection().ltrim(key, start, end); + public String execute(Jedis connection) { + return connection.ltrim(key, start, end); } }.run(key); } @@ -482,8 +482,8 @@ public class JedisCluster implements JedisCommands, BasicCommands { return new JedisClusterCommand(connectionHandler, timeout, maxRedirections) { @Override - public String execute() { - return connectionHandler.getConnection().lindex(key, index); + public String execute(Jedis connection) { + return connection.lindex(key, index); } }.run(key); } @@ -493,8 +493,8 @@ public class JedisCluster implements JedisCommands, BasicCommands { return new JedisClusterCommand(connectionHandler, timeout, maxRedirections) { @Override - public String execute() { - return connectionHandler.getConnection() + public String execute(Jedis connection) { + return connection .lset(key, index, value); } }.run(key); @@ -505,8 +505,8 @@ public class JedisCluster implements JedisCommands, BasicCommands { return new JedisClusterCommand(connectionHandler, timeout, maxRedirections) { @Override - public Long execute() { - return connectionHandler.getConnection() + public Long execute(Jedis connection) { + return connection .lrem(key, count, value); } }.run(key); @@ -517,8 +517,8 @@ public class JedisCluster implements JedisCommands, BasicCommands { return new JedisClusterCommand(connectionHandler, timeout, maxRedirections) { @Override - public String execute() { - return connectionHandler.getConnection().lpop(key); + public String execute(Jedis connection) { + return connection.lpop(key); } }.run(key); } @@ -528,8 +528,8 @@ public class JedisCluster implements JedisCommands, BasicCommands { return new JedisClusterCommand(connectionHandler, timeout, maxRedirections) { @Override - public String execute() { - return connectionHandler.getConnection().rpop(key); + public String execute(Jedis connection) { + return connection.rpop(key); } }.run(key); } @@ -539,8 +539,8 @@ public class JedisCluster implements JedisCommands, BasicCommands { return new JedisClusterCommand(connectionHandler, timeout, maxRedirections) { @Override - public Long execute() { - return connectionHandler.getConnection().sadd(key, member); + public Long execute(Jedis connection) { + return connection.sadd(key, member); } }.run(key); } @@ -550,8 +550,8 @@ public class JedisCluster implements JedisCommands, BasicCommands { return new JedisClusterCommand>(connectionHandler, timeout, maxRedirections) { @Override - public Set execute() { - return connectionHandler.getConnection().smembers(key); + public Set execute(Jedis connection) { + return connection.smembers(key); } }.run(key); } @@ -561,8 +561,8 @@ public class JedisCluster implements JedisCommands, BasicCommands { return new JedisClusterCommand(connectionHandler, timeout, maxRedirections) { @Override - public Long execute() { - return connectionHandler.getConnection().srem(key, member); + public Long execute(Jedis connection) { + return connection.srem(key, member); } }.run(key); } @@ -572,8 +572,8 @@ public class JedisCluster implements JedisCommands, BasicCommands { return new JedisClusterCommand(connectionHandler, timeout, maxRedirections) { @Override - public String execute() { - return connectionHandler.getConnection().spop(key); + public String execute(Jedis connection) { + return connection.spop(key); } }.run(key); } @@ -583,8 +583,8 @@ public class JedisCluster implements JedisCommands, BasicCommands { return new JedisClusterCommand(connectionHandler, timeout, maxRedirections) { @Override - public Long execute() { - return connectionHandler.getConnection().scard(key); + public Long execute(Jedis connection) { + return connection.scard(key); } }.run(key); } @@ -594,8 +594,8 @@ public class JedisCluster implements JedisCommands, BasicCommands { return new JedisClusterCommand(connectionHandler, timeout, maxRedirections) { @Override - public Boolean execute() { - return connectionHandler.getConnection().sismember(key, member); + public Boolean execute(Jedis connection) { + return connection.sismember(key, member); } }.run(key); } @@ -605,8 +605,8 @@ public class JedisCluster implements JedisCommands, BasicCommands { return new JedisClusterCommand(connectionHandler, timeout, maxRedirections) { @Override - public String execute() { - return connectionHandler.getConnection().srandmember(key); + public String execute(Jedis connection) { + return connection.srandmember(key); } }.run(key); } @@ -616,8 +616,8 @@ public class JedisCluster implements JedisCommands, BasicCommands { return new JedisClusterCommand(connectionHandler, timeout, maxRedirections) { @Override - public Long execute() { - return connectionHandler.getConnection().strlen(key); + public Long execute(Jedis connection) { + return connection.strlen(key); } }.run(key); } @@ -627,8 +627,8 @@ public class JedisCluster implements JedisCommands, BasicCommands { return new JedisClusterCommand(connectionHandler, timeout, maxRedirections) { @Override - public Long execute() { - return connectionHandler.getConnection().zadd(key, score, + public Long execute(Jedis connection) { + return connection.zadd(key, score, member); } }.run(key); @@ -639,8 +639,8 @@ public class JedisCluster implements JedisCommands, BasicCommands { return new JedisClusterCommand(connectionHandler, timeout, maxRedirections) { @Override - public Long execute() { - return connectionHandler.getConnection() + public Long execute(Jedis connection) { + return connection .zadd(key, scoreMembers); } }.run(key); @@ -651,8 +651,8 @@ public class JedisCluster implements JedisCommands, BasicCommands { return new JedisClusterCommand>(connectionHandler, timeout, maxRedirections) { @Override - public Set execute() { - return connectionHandler.getConnection() + public Set execute(Jedis connection) { + return connection .zrange(key, start, end); } }.run(key); @@ -663,8 +663,8 @@ public class JedisCluster implements JedisCommands, BasicCommands { return new JedisClusterCommand(connectionHandler, timeout, maxRedirections) { @Override - public Long execute() { - return connectionHandler.getConnection().zrem(key, member); + public Long execute(Jedis connection) { + return connection.zrem(key, member); } }.run(key); } @@ -675,8 +675,8 @@ public class JedisCluster implements JedisCommands, BasicCommands { return new JedisClusterCommand(connectionHandler, timeout, maxRedirections) { @Override - public Double execute() { - return connectionHandler.getConnection().zincrby(key, score, + public Double execute(Jedis connection) { + return connection.zincrby(key, score, member); } }.run(key); @@ -687,8 +687,8 @@ public class JedisCluster implements JedisCommands, BasicCommands { return new JedisClusterCommand(connectionHandler, timeout, maxRedirections) { @Override - public Long execute() { - return connectionHandler.getConnection().zrank(key, member); + public Long execute(Jedis connection) { + return connection.zrank(key, member); } }.run(key); } @@ -698,8 +698,8 @@ public class JedisCluster implements JedisCommands, BasicCommands { return new JedisClusterCommand(connectionHandler, timeout, maxRedirections) { @Override - public Long execute() { - return connectionHandler.getConnection().zrevrank(key, member); + public Long execute(Jedis connection) { + return connection.zrevrank(key, member); } }.run(key); } @@ -710,8 +710,8 @@ public class JedisCluster implements JedisCommands, BasicCommands { return new JedisClusterCommand>(connectionHandler, timeout, maxRedirections) { @Override - public Set execute() { - return connectionHandler.getConnection().zrevrange(key, start, + public Set execute(Jedis connection) { + return connection.zrevrange(key, start, end); } }.run(key); @@ -723,8 +723,8 @@ public class JedisCluster implements JedisCommands, BasicCommands { return new JedisClusterCommand>(connectionHandler, timeout, maxRedirections) { @Override - public Set execute() { - return connectionHandler.getConnection().zrangeWithScores(key, + public Set execute(Jedis connection) { + return connection.zrangeWithScores(key, start, end); } }.run(key); @@ -736,8 +736,8 @@ public class JedisCluster implements JedisCommands, BasicCommands { return new JedisClusterCommand>(connectionHandler, timeout, maxRedirections) { @Override - public Set execute() { - return connectionHandler.getConnection().zrevrangeWithScores( + public Set execute(Jedis connection) { + return connection.zrevrangeWithScores( key, start, end); } }.run(key); @@ -748,8 +748,8 @@ public class JedisCluster implements JedisCommands, BasicCommands { return new JedisClusterCommand(connectionHandler, timeout, maxRedirections) { @Override - public Long execute() { - return connectionHandler.getConnection().zcard(key); + public Long execute(Jedis connection) { + return connection.zcard(key); } }.run(key); } @@ -759,8 +759,8 @@ public class JedisCluster implements JedisCommands, BasicCommands { return new JedisClusterCommand(connectionHandler, timeout, maxRedirections) { @Override - public Double execute() { - return connectionHandler.getConnection().zscore(key, member); + public Double execute(Jedis connection) { + return connection.zscore(key, member); } }.run(key); } @@ -770,8 +770,8 @@ public class JedisCluster implements JedisCommands, BasicCommands { return new JedisClusterCommand>(connectionHandler, timeout, maxRedirections) { @Override - public List execute() { - return connectionHandler.getConnection().sort(key); + public List execute(Jedis connection) { + return connection.sort(key); } }.run(key); } @@ -782,8 +782,8 @@ public class JedisCluster implements JedisCommands, BasicCommands { return new JedisClusterCommand>(connectionHandler, timeout, maxRedirections) { @Override - public List execute() { - return connectionHandler.getConnection().sort(key, + public List execute(Jedis connection) { + return connection.sort(key, sortingParameters); } }.run(key); @@ -794,8 +794,8 @@ public class JedisCluster implements JedisCommands, BasicCommands { return new JedisClusterCommand(connectionHandler, timeout, maxRedirections) { @Override - public Long execute() { - return connectionHandler.getConnection().zcount(key, min, max); + public Long execute(Jedis connection) { + return connection.zcount(key, min, max); } }.run(key); } @@ -805,8 +805,8 @@ public class JedisCluster implements JedisCommands, BasicCommands { return new JedisClusterCommand(connectionHandler, timeout, maxRedirections) { @Override - public Long execute() { - return connectionHandler.getConnection().zcount(key, min, max); + public Long execute(Jedis connection) { + return connection.zcount(key, min, max); } }.run(key); } @@ -817,8 +817,8 @@ public class JedisCluster implements JedisCommands, BasicCommands { return new JedisClusterCommand>(connectionHandler, timeout, maxRedirections) { @Override - public Set execute() { - return connectionHandler.getConnection().zrangeByScore(key, + public Set execute(Jedis connection) { + return connection.zrangeByScore(key, min, max); } }.run(key); @@ -830,8 +830,8 @@ public class JedisCluster implements JedisCommands, BasicCommands { return new JedisClusterCommand>(connectionHandler, timeout, maxRedirections) { @Override - public Set execute() { - return connectionHandler.getConnection().zrangeByScore(key, + public Set execute(Jedis connection) { + return connection.zrangeByScore(key, min, max); } }.run(key); @@ -843,8 +843,8 @@ public class JedisCluster implements JedisCommands, BasicCommands { return new JedisClusterCommand>(connectionHandler, timeout, maxRedirections) { @Override - public Set execute() { - return connectionHandler.getConnection().zrevrangeByScore(key, + public Set execute(Jedis connection) { + return connection.zrevrangeByScore(key, min, max); } }.run(key); @@ -856,8 +856,8 @@ public class JedisCluster implements JedisCommands, BasicCommands { return new JedisClusterCommand>(connectionHandler, timeout, maxRedirections) { @Override - public Set execute() { - return connectionHandler.getConnection().zrangeByScore(key, + public Set execute(Jedis connection) { + return connection.zrangeByScore(key, min, max, offset, count); } }.run(key); @@ -869,8 +869,8 @@ public class JedisCluster implements JedisCommands, BasicCommands { return new JedisClusterCommand>(connectionHandler, timeout, maxRedirections) { @Override - public Set execute() { - return connectionHandler.getConnection().zrevrangeByScore(key, + public Set execute(Jedis connection) { + return connection.zrevrangeByScore(key, min, max); } }.run(key); @@ -882,8 +882,8 @@ public class JedisCluster implements JedisCommands, BasicCommands { return new JedisClusterCommand>(connectionHandler, timeout, maxRedirections) { @Override - public Set execute() { - return connectionHandler.getConnection().zrangeByScore(key, + public Set execute(Jedis connection) { + return connection.zrangeByScore(key, min, max, offset, count); } }.run(key); @@ -895,8 +895,8 @@ public class JedisCluster implements JedisCommands, BasicCommands { return new JedisClusterCommand>(connectionHandler, timeout, maxRedirections) { @Override - public Set execute() { - return connectionHandler.getConnection().zrevrangeByScore(key, + public Set execute(Jedis connection) { + return connection.zrevrangeByScore(key, min, max, offset, count); } }.run(key); @@ -908,8 +908,8 @@ public class JedisCluster implements JedisCommands, BasicCommands { return new JedisClusterCommand>(connectionHandler, timeout, maxRedirections) { @Override - public Set execute() { - return connectionHandler.getConnection() + public Set execute(Jedis connection) { + return connection .zrangeByScoreWithScores(key, min, max); } }.run(key); @@ -921,8 +921,8 @@ public class JedisCluster implements JedisCommands, BasicCommands { return new JedisClusterCommand>(connectionHandler, timeout, maxRedirections) { @Override - public Set execute() { - return connectionHandler.getConnection() + public Set execute(Jedis connection) { + return connection .zrevrangeByScoreWithScores(key, min, max); } }.run(key); @@ -935,8 +935,8 @@ public class JedisCluster implements JedisCommands, BasicCommands { return new JedisClusterCommand>(connectionHandler, timeout, maxRedirections) { @Override - public Set execute() { - return connectionHandler.getConnection() + public Set execute(Jedis connection) { + return connection .zrangeByScoreWithScores(key, min, max, offset, count); } }.run(key); @@ -948,8 +948,8 @@ public class JedisCluster implements JedisCommands, BasicCommands { return new JedisClusterCommand>(connectionHandler, timeout, maxRedirections) { @Override - public Set execute() { - return connectionHandler.getConnection().zrevrangeByScore(key, + public Set execute(Jedis connection) { + return connection.zrevrangeByScore(key, min, max, offset, count); } }.run(key); @@ -961,8 +961,8 @@ public class JedisCluster implements JedisCommands, BasicCommands { return new JedisClusterCommand>(connectionHandler, timeout, maxRedirections) { @Override - public Set execute() { - return connectionHandler.getConnection() + public Set execute(Jedis connection) { + return connection .zrangeByScoreWithScores(key, min, max); } }.run(key); @@ -974,8 +974,8 @@ public class JedisCluster implements JedisCommands, BasicCommands { return new JedisClusterCommand>(connectionHandler, timeout, maxRedirections) { @Override - public Set execute() { - return connectionHandler.getConnection() + public Set execute(Jedis connection) { + return connection .zrevrangeByScoreWithScores(key, min, max); } }.run(key); @@ -988,8 +988,8 @@ public class JedisCluster implements JedisCommands, BasicCommands { return new JedisClusterCommand>(connectionHandler, timeout, maxRedirections) { @Override - public Set execute() { - return connectionHandler.getConnection() + public Set execute(Jedis connection) { + return connection .zrangeByScoreWithScores(key, min, max, offset, count); } }.run(key); @@ -1002,8 +1002,8 @@ public class JedisCluster implements JedisCommands, BasicCommands { return new JedisClusterCommand>(connectionHandler, timeout, maxRedirections) { @Override - public Set execute() { - return connectionHandler.getConnection() + public Set execute(Jedis connection) { + return connection .zrevrangeByScoreWithScores(key, max, min, offset, count); } @@ -1017,8 +1017,8 @@ public class JedisCluster implements JedisCommands, BasicCommands { return new JedisClusterCommand>(connectionHandler, timeout, maxRedirections) { @Override - public Set execute() { - return connectionHandler.getConnection() + public Set execute(Jedis connection) { + return connection .zrevrangeByScoreWithScores(key, max, min, offset, count); } @@ -1031,8 +1031,8 @@ public class JedisCluster implements JedisCommands, BasicCommands { return new JedisClusterCommand(connectionHandler, timeout, maxRedirections) { @Override - public Long execute() { - return connectionHandler.getConnection().zremrangeByRank(key, + public Long execute(Jedis connection) { + return connection.zremrangeByRank(key, start, end); } }.run(key); @@ -1044,8 +1044,8 @@ public class JedisCluster implements JedisCommands, BasicCommands { return new JedisClusterCommand(connectionHandler, timeout, maxRedirections) { @Override - public Long execute() { - return connectionHandler.getConnection().zremrangeByScore(key, + public Long execute(Jedis connection) { + return connection.zremrangeByScore(key, start, end); } }.run(key); @@ -1057,8 +1057,8 @@ public class JedisCluster implements JedisCommands, BasicCommands { return new JedisClusterCommand(connectionHandler, timeout, maxRedirections) { @Override - public Long execute() { - return connectionHandler.getConnection().zremrangeByScore(key, + public Long execute(Jedis connection) { + return connection.zremrangeByScore(key, start, end); } }.run(key); @@ -1070,8 +1070,8 @@ public class JedisCluster implements JedisCommands, BasicCommands { return new JedisClusterCommand(connectionHandler, timeout, maxRedirections) { @Override - public Long execute() { - return connectionHandler.getConnection().linsert(key, where, + public Long execute(Jedis connection) { + return connection.linsert(key, where, pivot, value); } }.run(key); @@ -1082,8 +1082,8 @@ public class JedisCluster implements JedisCommands, BasicCommands { return new JedisClusterCommand(connectionHandler, timeout, maxRedirections) { @Override - public Long execute() { - return connectionHandler.getConnection().lpushx(key, string); + public Long execute(Jedis connection) { + return connection.lpushx(key, string); } }.run(key); } @@ -1093,8 +1093,8 @@ public class JedisCluster implements JedisCommands, BasicCommands { return new JedisClusterCommand(connectionHandler, timeout, maxRedirections) { @Override - public Long execute() { - return connectionHandler.getConnection().rpushx(key, string); + public Long execute(Jedis connection) { + return connection.rpushx(key, string); } }.run(key); } @@ -1104,8 +1104,8 @@ public class JedisCluster implements JedisCommands, BasicCommands { return new JedisClusterCommand>(connectionHandler, timeout, maxRedirections) { @Override - public List execute() { - return connectionHandler.getConnection().blpop(arg); + public List execute(Jedis connection) { + return connection.blpop(arg); } }.run(null); } @@ -1115,8 +1115,8 @@ public class JedisCluster implements JedisCommands, BasicCommands { return new JedisClusterCommand>(connectionHandler, timeout, maxRedirections) { @Override - public List execute() { - return connectionHandler.getConnection().brpop(arg); + public List execute(Jedis connection) { + return connection.brpop(arg); } }.run(null); } @@ -1126,8 +1126,8 @@ public class JedisCluster implements JedisCommands, BasicCommands { return new JedisClusterCommand(connectionHandler, timeout, maxRedirections) { @Override - public Long execute() { - return connectionHandler.getConnection().del(key); + public Long execute(Jedis connection) { + return connection.del(key); } }.run(null); } @@ -1137,8 +1137,8 @@ public class JedisCluster implements JedisCommands, BasicCommands { return new JedisClusterCommand(connectionHandler, timeout, maxRedirections) { @Override - public String execute() { - return connectionHandler.getConnection().echo(string); + public String execute(Jedis connection) { + return connection.echo(string); } }.run(null); } @@ -1148,8 +1148,8 @@ public class JedisCluster implements JedisCommands, BasicCommands { return new JedisClusterCommand(connectionHandler, timeout, maxRedirections) { @Override - public Long execute() { - return connectionHandler.getConnection().move(key, dbIndex); + public Long execute(Jedis connection) { + return connection.move(key, dbIndex); } }.run(key); } @@ -1159,8 +1159,8 @@ public class JedisCluster implements JedisCommands, BasicCommands { return new JedisClusterCommand(connectionHandler, timeout, maxRedirections) { @Override - public Long execute() { - return connectionHandler.getConnection().bitcount(key); + public Long execute(Jedis connection) { + return connection.bitcount(key); } }.run(key); } @@ -1170,8 +1170,8 @@ public class JedisCluster implements JedisCommands, BasicCommands { return new JedisClusterCommand(connectionHandler, timeout, maxRedirections) { @Override - public Long execute() { - return connectionHandler.getConnection().bitcount(key, start, + public Long execute(Jedis connection) { + return connection.bitcount(key, start, end); } }.run(key); @@ -1182,8 +1182,8 @@ public class JedisCluster implements JedisCommands, BasicCommands { return new JedisClusterCommand(connectionHandler, timeout, maxRedirections) { @Override - public String execute() { - return connectionHandler.getConnection().ping(); + public String execute(Jedis connection) { + return connection.ping(); } }.run(null); } @@ -1193,8 +1193,8 @@ public class JedisCluster implements JedisCommands, BasicCommands { return new JedisClusterCommand(connectionHandler, timeout, maxRedirections) { @Override - public String execute() { - return connectionHandler.getConnection().quit(); + public String execute(Jedis connection) { + return connection.quit(); } }.run(null); } @@ -1204,8 +1204,8 @@ public class JedisCluster implements JedisCommands, BasicCommands { return new JedisClusterCommand(connectionHandler, timeout, maxRedirections) { @Override - public String execute() { - return connectionHandler.getConnection().flushDB(); + public String execute(Jedis connection) { + return connection.flushDB(); } }.run(null); } @@ -1215,8 +1215,8 @@ public class JedisCluster implements JedisCommands, BasicCommands { return new JedisClusterCommand(connectionHandler, timeout, maxRedirections) { @Override - public Long execute() { - return connectionHandler.getConnection().dbSize(); + public Long execute(Jedis connection) { + return connection.dbSize(); } }.run(null); } @@ -1226,8 +1226,8 @@ public class JedisCluster implements JedisCommands, BasicCommands { return new JedisClusterCommand(connectionHandler, timeout, maxRedirections) { @Override - public String execute() { - return connectionHandler.getConnection().select(index); + public String execute(Jedis connection) { + return connection.select(index); } }.run(null); } @@ -1237,8 +1237,8 @@ public class JedisCluster implements JedisCommands, BasicCommands { return new JedisClusterCommand(connectionHandler, timeout, maxRedirections) { @Override - public String execute() { - return connectionHandler.getConnection().flushAll(); + public String execute(Jedis connection) { + return connection.flushAll(); } }.run(null); } @@ -1248,8 +1248,8 @@ public class JedisCluster implements JedisCommands, BasicCommands { return new JedisClusterCommand(connectionHandler, timeout, maxRedirections) { @Override - public String execute() { - return connectionHandler.getConnection().auth(password); + public String execute(Jedis connection) { + return connection.auth(password); } }.run(null); } @@ -1259,8 +1259,8 @@ public class JedisCluster implements JedisCommands, BasicCommands { return new JedisClusterCommand(connectionHandler, timeout, maxRedirections) { @Override - public String execute() { - return connectionHandler.getConnection().save(); + public String execute(Jedis connection) { + return connection.save(); } }.run(null); } @@ -1270,8 +1270,8 @@ public class JedisCluster implements JedisCommands, BasicCommands { return new JedisClusterCommand(connectionHandler, timeout, maxRedirections) { @Override - public String execute() { - return connectionHandler.getConnection().bgsave(); + public String execute(Jedis connection) { + return connection.bgsave(); } }.run(null); } @@ -1281,8 +1281,8 @@ public class JedisCluster implements JedisCommands, BasicCommands { return new JedisClusterCommand(connectionHandler, timeout, maxRedirections) { @Override - public String execute() { - return connectionHandler.getConnection().bgrewriteaof(); + public String execute(Jedis connection) { + return connection.bgrewriteaof(); } }.run(null); } @@ -1292,8 +1292,8 @@ public class JedisCluster implements JedisCommands, BasicCommands { return new JedisClusterCommand(connectionHandler, timeout, maxRedirections) { @Override - public Long execute() { - return connectionHandler.getConnection().lastsave(); + public Long execute(Jedis connection) { + return connection.lastsave(); } }.run(null); } @@ -1303,8 +1303,8 @@ public class JedisCluster implements JedisCommands, BasicCommands { return new JedisClusterCommand(connectionHandler, timeout, maxRedirections) { @Override - public String execute() { - return connectionHandler.getConnection().shutdown(); + public String execute(Jedis connection) { + return connection.shutdown(); } }.run(null); } @@ -1314,8 +1314,8 @@ public class JedisCluster implements JedisCommands, BasicCommands { return new JedisClusterCommand(connectionHandler, timeout, maxRedirections) { @Override - public String execute() { - return connectionHandler.getConnection().info(); + public String execute(Jedis connection) { + return connection.info(); } }.run(null); } @@ -1325,8 +1325,8 @@ public class JedisCluster implements JedisCommands, BasicCommands { return new JedisClusterCommand(connectionHandler, timeout, maxRedirections) { @Override - public String execute() { - return connectionHandler.getConnection().info(section); + public String execute(Jedis connection) { + return connection.info(section); } }.run(null); } @@ -1336,8 +1336,8 @@ public class JedisCluster implements JedisCommands, BasicCommands { return new JedisClusterCommand(connectionHandler, timeout, maxRedirections) { @Override - public String execute() { - return connectionHandler.getConnection().slaveof(host, port); + public String execute(Jedis connection) { + return connection.slaveof(host, port); } }.run(null); } @@ -1347,8 +1347,8 @@ public class JedisCluster implements JedisCommands, BasicCommands { return new JedisClusterCommand(connectionHandler, timeout, maxRedirections) { @Override - public String execute() { - return connectionHandler.getConnection().slaveofNoOne(); + public String execute(Jedis connection) { + return connection.slaveofNoOne(); } }.run(null); } @@ -1358,8 +1358,8 @@ public class JedisCluster implements JedisCommands, BasicCommands { return new JedisClusterCommand(connectionHandler, timeout, maxRedirections) { @Override - public Long execute() { - return connectionHandler.getConnection().getDB(); + public Long execute(Jedis connection) { + return connection.getDB(); } }.run(null); } @@ -1369,8 +1369,8 @@ public class JedisCluster implements JedisCommands, BasicCommands { return new JedisClusterCommand(connectionHandler, timeout, maxRedirections) { @Override - public String execute() { - return connectionHandler.getConnection().debug(params); + public String execute(Jedis connection) { + return connection.debug(params); } }.run(null); } @@ -1380,8 +1380,8 @@ public class JedisCluster implements JedisCommands, BasicCommands { return new JedisClusterCommand(connectionHandler, timeout, maxRedirections) { @Override - public String execute() { - return connectionHandler.getConnection().configResetStat(); + public String execute(Jedis connection) { + return connection.configResetStat(); } }.run(null); } @@ -1408,8 +1408,8 @@ public class JedisCluster implements JedisCommands, BasicCommands { return new JedisClusterCommand>>( connectionHandler, timeout, maxRedirections) { @Override - public ScanResult> execute() { - return connectionHandler.getConnection().hscan(key, cursor); + public ScanResult> execute(Jedis connection) { + return connection.hscan(key, cursor); } }.run(null); } @@ -1425,8 +1425,8 @@ public class JedisCluster implements JedisCommands, BasicCommands { return new JedisClusterCommand>(connectionHandler, timeout, maxRedirections) { @Override - public ScanResult execute() { - return connectionHandler.getConnection().sscan(key, cursor); + public ScanResult execute(Jedis connection) { + return connection.sscan(key, cursor); } }.run(null); } @@ -1442,8 +1442,8 @@ public class JedisCluster implements JedisCommands, BasicCommands { return new JedisClusterCommand>(connectionHandler, timeout, maxRedirections) { @Override - public ScanResult execute() { - return connectionHandler.getConnection().zscan(key, cursor); + public ScanResult execute(Jedis connection) { + return connection.zscan(key, cursor); } }.run(null); } @@ -1454,8 +1454,8 @@ public class JedisCluster implements JedisCommands, BasicCommands { return new JedisClusterCommand>>( connectionHandler, timeout, maxRedirections) { @Override - public ScanResult> execute() { - return connectionHandler.getConnection().hscan(key, cursor); + public ScanResult> execute(Jedis connection) { + return connection.hscan(key, cursor); } }.run(null); } @@ -1465,8 +1465,8 @@ public class JedisCluster implements JedisCommands, BasicCommands { return new JedisClusterCommand>(connectionHandler, timeout, maxRedirections) { @Override - public ScanResult execute() { - return connectionHandler.getConnection().sscan(key, cursor); + public ScanResult execute(Jedis connection) { + return connection.sscan(key, cursor); } }.run(null); } @@ -1476,8 +1476,8 @@ public class JedisCluster implements JedisCommands, BasicCommands { return new JedisClusterCommand>(connectionHandler, timeout, maxRedirections) { @Override - public ScanResult execute() { - return connectionHandler.getConnection().zscan(key, cursor); + public ScanResult execute(Jedis connection) { + return connection.zscan(key, cursor); } }.run(null); } diff --git a/src/main/java/redis/clients/jedis/JedisClusterCommand.java b/src/main/java/redis/clients/jedis/JedisClusterCommand.java index 41087a7..6e110bc 100644 --- a/src/main/java/redis/clients/jedis/JedisClusterCommand.java +++ b/src/main/java/redis/clients/jedis/JedisClusterCommand.java @@ -23,9 +23,10 @@ public abstract class JedisClusterCommand { this.redirections = maxRedirections; } - public abstract T execute(); + public abstract T execute(Jedis connection); public T run(String key) { + Jedis connection = null; try { if (key == null) { @@ -35,16 +36,20 @@ public abstract class JedisClusterCommand { throw new JedisClusterMaxRedirectionsException( "Too many Cluster redirections?"); } - connectionHandler.getConnectionFromSlot(JedisClusterCRC16 + connection = connectionHandler.getConnectionFromSlot(JedisClusterCRC16 .getSlot(key)); if (asking) { // TODO: Pipeline asking with the original command to make it // faster.... - connectionHandler.getConnection().asking(); + connection.asking(); } - return execute(); + return execute(connection); } catch (JedisRedirectionException jre) { return handleRedirection(jre, key); + } finally { + if (connection != null) { + connectionHandler.returnConnection(connection); + } } } diff --git a/src/main/java/redis/clients/jedis/JedisClusterConnectionHandler.java b/src/main/java/redis/clients/jedis/JedisClusterConnectionHandler.java index d30b5f7..28e22f9 100644 --- a/src/main/java/redis/clients/jedis/JedisClusterConnectionHandler.java +++ b/src/main/java/redis/clients/jedis/JedisClusterConnectionHandler.java @@ -11,6 +11,13 @@ public abstract class JedisClusterConnectionHandler { protected Map slots = new HashMap(); abstract Jedis getConnection(); + + protected void returnConnection(Jedis connection) { + nodes.get( + connection.getClient().getHost() + + connection.getClient().getPort()).returnResource( + connection); + } abstract Jedis getConnectionFromSlot(int slot); diff --git a/src/main/java/redis/clients/jedis/JedisSlotBasedConnectionHandler.java b/src/main/java/redis/clients/jedis/JedisSlotBasedConnectionHandler.java index 4aba893..76b52d0 100644 --- a/src/main/java/redis/clients/jedis/JedisSlotBasedConnectionHandler.java +++ b/src/main/java/redis/clients/jedis/JedisSlotBasedConnectionHandler.java @@ -5,25 +5,12 @@ import java.util.Set; public class JedisSlotBasedConnectionHandler extends JedisClusterConnectionHandler { - private Jedis currentConnection; - public JedisSlotBasedConnectionHandler(Set nodes) { super(nodes); } public Jedis getConnection() { - return currentConnection != null ? currentConnection - : getRandomConnection().getResource(); - } - - private void returnCurrentConnection() { - if (currentConnection != null) { - nodes.get( - currentConnection.getClient().getHost() - + currentConnection.getClient().getPort()) - .returnResource(currentConnection); - } - + return getRandomConnection().getResource(); } @Override @@ -34,13 +21,11 @@ public class JedisSlotBasedConnectionHandler extends @Override public Jedis getConnectionFromSlot(int slot) { - returnCurrentConnection(); JedisPool connectionPool = slots.get(slot); if (connectionPool == null) { connectionPool = getRandomConnection(); } - currentConnection = connectionPool.getResource(); - return connectionPool.getResource(); + return connectionPool.getResource(); } } From 3f8507a1171cb3b048c1fa72be3eb1c3bec15a36 Mon Sep 17 00:00:00 2001 From: Marcos Nils Date: Thu, 20 Feb 2014 14:39:51 -0300 Subject: [PATCH 03/16] Remove unnecessary connection allocation --- .../redis/clients/jedis/JedisSlotBasedConnectionHandler.java | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/main/java/redis/clients/jedis/JedisSlotBasedConnectionHandler.java b/src/main/java/redis/clients/jedis/JedisSlotBasedConnectionHandler.java index 76b52d0..18aa424 100644 --- a/src/main/java/redis/clients/jedis/JedisSlotBasedConnectionHandler.java +++ b/src/main/java/redis/clients/jedis/JedisSlotBasedConnectionHandler.java @@ -16,7 +16,6 @@ public class JedisSlotBasedConnectionHandler extends @Override public void assignSlotToNode(int slot, HostAndPort targetNode) { super.assignSlotToNode(slot, targetNode); - getConnectionFromSlot(slot); } @Override @@ -25,7 +24,7 @@ public class JedisSlotBasedConnectionHandler extends if (connectionPool == null) { connectionPool = getRandomConnection(); } - return connectionPool.getResource(); + return connectionPool.getResource(); } } From 756113821f2599e72bfece457094bc51a1fcc7c2 Mon Sep 17 00:00:00 2001 From: Marcos Nils Date: Thu, 20 Feb 2014 14:58:04 -0300 Subject: [PATCH 04/16] Make JedisClusterCRC16 multi-thread --- src/main/java/redis/clients/util/JedisClusterCRC16.java | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/main/java/redis/clients/util/JedisClusterCRC16.java b/src/main/java/redis/clients/util/JedisClusterCRC16.java index 3c5c9b5..270dbf0 100644 --- a/src/main/java/redis/clients/util/JedisClusterCRC16.java +++ b/src/main/java/redis/clients/util/JedisClusterCRC16.java @@ -2,7 +2,6 @@ package redis.clients.util; public class JedisClusterCRC16 { public final static int polynomial = 0x1021; // Represents x^16+x^12+x^5+1 - static int crc; public static int getSlot(String key) { @@ -17,7 +16,7 @@ public class JedisClusterCRC16 { } private static int getCRC16(String key) { - crc = 0x0000; + int crc = 0x0000; for (byte b : key.getBytes()) { for (int i = 0; i < 8; i++) { boolean bit = ((b >> (7 - i) & 1) == 1); From 882d662470351d08d106006821c837d76b5ddaac Mon Sep 17 00:00:00 2001 From: Jungtaek Lim Date: Tue, 25 Feb 2014 18:29:09 +0900 Subject: [PATCH 05/16] Make Jedis Cluster more likely to antirez's redis-rb-cluster JedisClusterCommand * improvements on connection error handling ** if based on slot connection throws connection related exception, retry to random node ** if we retry with random node, but all nodes are unreachable, throw JedisConnectionException without retry ** try to release connection whether connection is broken or not * bug fix : if asking flag is on, and success this time, set asking flag to off JedisClusterConnectionHandler * have flexibility on initializing slots cache ** allow some nodes connection failure - skip ** if current node is success initializing slots cache, skip other nodes ** if current node failed to initialize slots cache, discard all discovered nodes and slots * set nodes if node does not exist in nodes ** it restricts JedisPool to replace - prevent IllegalStateException : Returned object not currently part of this pool JedisSlotBasedConnectionGuaranteedConnectionHandler * getConnection (random connection) ** check all connections by random sequence ** always return valid connection (able to ping-pong) ** throw exception if all connections are invalid * some refactoring --- .../redis/clients/jedis/JedisCluster.java | 2 +- .../clients/jedis/JedisClusterCommand.java | 87 ++++++++++++++----- .../jedis/JedisClusterConnectionHandler.java | 80 +++++++++++++---- ...ConnectionGuaranteedConnectionHandler.java | 68 +++++++++++++++ 4 files changed, 196 insertions(+), 41 deletions(-) create mode 100644 src/main/java/redis/clients/jedis/JedisSlotBasedConnectionGuaranteedConnectionHandler.java diff --git a/src/main/java/redis/clients/jedis/JedisCluster.java b/src/main/java/redis/clients/jedis/JedisCluster.java index 1f645ea..afa0109 100644 --- a/src/main/java/redis/clients/jedis/JedisCluster.java +++ b/src/main/java/redis/clients/jedis/JedisCluster.java @@ -27,7 +27,7 @@ public class JedisCluster implements JedisCommands, BasicCommands { public JedisCluster(Set jedisClusterNode, int timeout, int maxRedirections) { - this.connectionHandler = new JedisSlotBasedConnectionHandler( + this.connectionHandler = new JedisSlotBasedConnectionGuaranteedConnectionHandler( jedisClusterNode); this.timeout = timeout; this.maxRedirections = maxRedirections; diff --git a/src/main/java/redis/clients/jedis/JedisClusterCommand.java b/src/main/java/redis/clients/jedis/JedisClusterCommand.java index 6e110bc..c1be912 100644 --- a/src/main/java/redis/clients/jedis/JedisClusterCommand.java +++ b/src/main/java/redis/clients/jedis/JedisClusterCommand.java @@ -3,19 +3,18 @@ package redis.clients.jedis; import redis.clients.jedis.exceptions.JedisAskDataException; import redis.clients.jedis.exceptions.JedisClusterException; import redis.clients.jedis.exceptions.JedisClusterMaxRedirectionsException; +import redis.clients.jedis.exceptions.JedisConnectionException; +import redis.clients.jedis.exceptions.JedisException; +import redis.clients.jedis.exceptions.JedisMovedDataException; import redis.clients.jedis.exceptions.JedisRedirectionException; import redis.clients.util.JedisClusterCRC16; public abstract class JedisClusterCommand { - private boolean asking = false; - private JedisClusterConnectionHandler connectionHandler; private int commandTimeout; private int redirections; - // private boolean asking = false; - public JedisClusterCommand(JedisClusterConnectionHandler connectionHandler, int timeout, int maxRedirections) { this.connectionHandler = connectionHandler; @@ -26,40 +25,80 @@ public abstract class JedisClusterCommand { public abstract T execute(Jedis connection); public T run(String key) { + if (key == null) { + throw new JedisClusterException( + "No way to dispatch this command to Redis Cluster."); + } + + return runWithRetries(key, this.redirections, false, false); + } + + private T runWithRetries(String key, int redirections, + boolean tryRandomNode, boolean asking) { + if (redirections <= 0) { + throw new JedisClusterMaxRedirectionsException( + "Too many Cluster redirections?"); + } + Jedis connection = null; try { - - if (key == null) { - throw new JedisClusterException( - "No way to dispatch this command to Redis Cluster."); - } else if (redirections == 0) { - throw new JedisClusterMaxRedirectionsException( - "Too many Cluster redirections?"); + if (tryRandomNode) { + connection = connectionHandler.getConnection(); + } else { + connection = connectionHandler + .getConnectionFromSlot(JedisClusterCRC16.getSlot(key)); } - connection = connectionHandler.getConnectionFromSlot(JedisClusterCRC16 - .getSlot(key)); + if (asking) { // TODO: Pipeline asking with the original command to make it // faster.... connection.asking(); + + // if asking success, reset asking flag + asking = false; } + return execute(connection); + } catch (JedisConnectionException jce) { + if (tryRandomNode) { + // maybe all connection is down + throw jce; + } + + releaseConnection(connection, true); + connection = null; + + // retry with random connection + return runWithRetries(key, redirections--, true, asking); } catch (JedisRedirectionException jre) { - return handleRedirection(jre, key); + if (jre instanceof JedisAskDataException) { + asking = true; + } else if (jre instanceof JedisMovedDataException) { + // TODO : In antirez's redis-rb-cluster implementation, + // it rebuilds cluster's slot and node cache + } + + this.connectionHandler.assignSlotToNode(jre.getSlot(), + jre.getTargetNode()); + + releaseConnection(connection, false); + connection = null; + + return runWithRetries(key, redirections - 1, false, asking); } finally { - if (connection != null) { + releaseConnection(connection, false); + } + + } + + private void releaseConnection(Jedis connection, boolean broken) { + if (connection != null) { + if (broken) { + connectionHandler.returnBrokenConnection(connection); + } else { connectionHandler.returnConnection(connection); } } } - private T handleRedirection(JedisRedirectionException jre, String key) { - if (jre instanceof JedisAskDataException) { - asking = true; - } - redirections--; - this.connectionHandler.assignSlotToNode(jre.getSlot(), - jre.getTargetNode()); - return run(key); - } } \ No newline at end of file diff --git a/src/main/java/redis/clients/jedis/JedisClusterConnectionHandler.java b/src/main/java/redis/clients/jedis/JedisClusterConnectionHandler.java index 28e22f9..94f4c75 100644 --- a/src/main/java/redis/clients/jedis/JedisClusterConnectionHandler.java +++ b/src/main/java/redis/clients/jedis/JedisClusterConnectionHandler.java @@ -5,17 +5,22 @@ import java.util.Map; import java.util.Random; import java.util.Set; +import redis.clients.jedis.exceptions.JedisConnectionException; + public abstract class JedisClusterConnectionHandler { protected Map nodes = new HashMap(); protected Map slots = new HashMap(); abstract Jedis getConnection(); - + protected void returnConnection(Jedis connection) { - nodes.get( - connection.getClient().getHost() - + connection.getClient().getPort()).returnResource( + nodes.get(getNodeKey(connection.getClient())) + .returnResource(connection); + } + + public void returnBrokenConnection(Jedis connection) { + nodes.get(getNodeKey(connection.getClient())).returnBrokenResource( connection); } @@ -29,29 +34,57 @@ public abstract class JedisClusterConnectionHandler { return nodes; } - private void initializeSlotsCache(Set nodes) { - for (HostAndPort hostAndPort : nodes) { + private void initializeSlotsCache(Set startNodes) { + for (HostAndPort hostAndPort : startNodes) { JedisPool jp = new JedisPool(hostAndPort.getHost(), hostAndPort.getPort()); - this.nodes.put(hostAndPort.getHost() + hostAndPort.getPort(), jp); - Jedis jedis = jp.getResource(); + + this.nodes.clear(); + this.slots.clear(); + + Jedis jedis = null; try { + jedis = jp.getResource(); discoverClusterNodesAndSlots(jedis); + break; + } catch (JedisConnectionException e) { + if (jedis != null) { + jp.returnBrokenResource(jedis); + jedis = null; + } + + // try next nodes } finally { - jp.returnResource(jedis); + if (jedis != null) { + jp.returnResource(jedis); + } } } - } + for (HostAndPort node : startNodes) { + setNodeIfNotExist(node); + } + } + private void discoverClusterNodesAndSlots(Jedis jedis) { String localNodes = jedis.clusterNodes(); for (String nodeInfo : localNodes.split("\n")) { HostAndPort node = getHostAndPortFromNodeLine(nodeInfo, jedis); - JedisPool nodePool = new JedisPool(node.getHost(), node.getPort()); - this.nodes.put(node.getHost() + node.getPort(), nodePool); + setNodeIfNotExist(node); + + JedisPool nodePool = nodes.get(getNodeKey(node)); populateNodeSlots(nodeInfo, nodePool); } } + + private void setNodeIfNotExist(HostAndPort node) { + String nodeKey = getNodeKey(node); + if (nodes.containsKey(nodeKey)) + return; + + JedisPool nodePool = new JedisPool(node.getHost(), node.getPort()); + nodes.put(nodeKey, nodePool); + } private void populateNodeSlots(String nodeInfo, JedisPool nodePool) { String[] nodeInfoArray = nodeInfo.split(" "); @@ -74,7 +107,8 @@ public abstract class JedisClusterConnectionHandler { } } - private HostAndPort getHostAndPortFromNodeLine(String nodeInfo, Jedis currentConnection) { + private HostAndPort getHostAndPortFromNodeLine(String nodeInfo, + Jedis currentConnection) { String stringHostAndPort = nodeInfo.split(" ", 3)[1]; if (":0".equals(stringHostAndPort)) { return new HostAndPort(currentConnection.getClient().getHost(), @@ -86,9 +120,16 @@ public abstract class JedisClusterConnectionHandler { } public void assignSlotToNode(int slot, HostAndPort targetNode) { - JedisPool targetPool = nodes.get(targetNode.getHost() - + targetNode.getPort()); - slots.put(slot, targetPool); + JedisPool targetPool = nodes.get(getNodeKey(targetNode)); + + if (targetPool != null) { + slots.put(slot, targetPool); + } else { + setNodeIfNotExist(targetNode); + + targetPool = nodes.get(getNodeKey(targetNode)); + slots.put(slot, targetPool); + } } protected JedisPool getRandomConnection() { @@ -96,4 +137,11 @@ public abstract class JedisClusterConnectionHandler { return (JedisPool) (nodeArray[new Random().nextInt(nodeArray.length)]); } + protected String getNodeKey(HostAndPort hnp) { + return hnp.getHost() + ":" + hnp.getPort(); + } + + protected String getNodeKey(Client client) { + return client.getHost() + ":" + client.getPort(); + } } diff --git a/src/main/java/redis/clients/jedis/JedisSlotBasedConnectionGuaranteedConnectionHandler.java b/src/main/java/redis/clients/jedis/JedisSlotBasedConnectionGuaranteedConnectionHandler.java new file mode 100644 index 0000000..0fe2cec --- /dev/null +++ b/src/main/java/redis/clients/jedis/JedisSlotBasedConnectionGuaranteedConnectionHandler.java @@ -0,0 +1,68 @@ +package redis.clients.jedis; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import java.util.Set; + +import redis.clients.jedis.exceptions.JedisConnectionException; + +public class JedisSlotBasedConnectionGuaranteedConnectionHandler extends + JedisSlotBasedConnectionHandler { + + public JedisSlotBasedConnectionGuaranteedConnectionHandler( + Set nodes) { + super(nodes); + } + + public Jedis getConnection() { + // In antirez's redis-rb-cluster implementation, + // getRandomConnection always return valid connection (able to ping-pong) + // or exception if all connections are invalid + + List pools = getShuffledNodesPool(); + + for (JedisPool pool : pools) { + Jedis jedis = null; + try { + jedis = pool.getResource(); + + if (jedis == null) { + continue; + } + + String result = jedis.ping(); + + if (result.equalsIgnoreCase("pong")) + return jedis; + + pool.returnBrokenResource(jedis); + } catch (JedisConnectionException ex) { + if (jedis != null) { + pool.returnBrokenResource(jedis); + } + } + } + + throw new JedisConnectionException("no reachable node in cluster"); + } + + @Override + public Jedis getConnectionFromSlot(int slot) { + JedisPool connectionPool = slots.get(slot); + if (connectionPool != null) { + // It can't guaranteed to get valid connection because of node assignment + return connectionPool.getResource(); + } else { + return getConnection(); + } + } + + private List getShuffledNodesPool() { + List pools = new ArrayList(); + pools.addAll(nodes.values()); + Collections.shuffle(pools); + return pools; + } + +} From fcea0fe0feca0d2b4160a377ecf79c90c9dcda7d Mon Sep 17 00:00:00 2001 From: Jungtaek Lim Date: Wed, 26 Feb 2014 07:54:08 +0900 Subject: [PATCH 06/16] CLUSTERDOWN : JedisClusterException --- src/main/java/redis/clients/jedis/Protocol.java | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/main/java/redis/clients/jedis/Protocol.java b/src/main/java/redis/clients/jedis/Protocol.java index a753f96..681bc56 100644 --- a/src/main/java/redis/clients/jedis/Protocol.java +++ b/src/main/java/redis/clients/jedis/Protocol.java @@ -5,6 +5,7 @@ import java.util.ArrayList; import java.util.List; import redis.clients.jedis.exceptions.JedisAskDataException; +import redis.clients.jedis.exceptions.JedisClusterException; import redis.clients.jedis.exceptions.JedisConnectionException; import redis.clients.jedis.exceptions.JedisDataException; import redis.clients.jedis.exceptions.JedisMovedDataException; @@ -16,6 +17,7 @@ public final class Protocol { private static final String ASK_RESPONSE = "ASK"; private static final String MOVED_RESPONSE = "MOVED"; + private static final String CLUSTERDOWN_RESPONSE = "CLUSTERDOWN"; public static final int DEFAULT_PORT = 6379; public static final int DEFAULT_SENTINEL_PORT = 26379; public static final int DEFAULT_TIMEOUT = 2000; @@ -96,6 +98,8 @@ public final class Protocol { throw new JedisAskDataException(message, new HostAndPort( askInfo[1], Integer.valueOf(askInfo[2])), Integer.valueOf(askInfo[0])); + } else if (message.startsWith(CLUSTERDOWN_RESPONSE)) { + throw new JedisClusterException(message); } throw new JedisDataException(message); } From ddb1870a5f6781f909d9cd803bc0ac17e8846457 Mon Sep 17 00:00:00 2001 From: Marcos Nils Date: Thu, 27 Feb 2014 10:48:46 -0300 Subject: [PATCH 07/16] Fix bug in JedisCluster del command. Fix #568 --- src/main/java/redis/clients/jedis/JedisCluster.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/redis/clients/jedis/JedisCluster.java b/src/main/java/redis/clients/jedis/JedisCluster.java index 1f645ea..121bde8 100644 --- a/src/main/java/redis/clients/jedis/JedisCluster.java +++ b/src/main/java/redis/clients/jedis/JedisCluster.java @@ -1129,7 +1129,7 @@ public class JedisCluster implements JedisCommands, BasicCommands { public Long execute(Jedis connection) { return connection.del(key); } - }.run(null); + }.run(key); } @Override From 46eef9530b4a6f493ed1ab1e677213467461bfbe Mon Sep 17 00:00:00 2001 From: Henning Schmiedehausen Date: Thu, 27 Feb 2014 10:58:46 -0800 Subject: [PATCH 08/16] add a number of null check to return methods. This allows calling these methods on error cleanup paths without having to surround them with if checks all the time. --- src/main/java/redis/clients/jedis/JedisPool.java | 10 +++++++--- src/main/java/redis/clients/util/Pool.java | 10 +++++++--- 2 files changed, 14 insertions(+), 6 deletions(-) diff --git a/src/main/java/redis/clients/jedis/JedisPool.java b/src/main/java/redis/clients/jedis/JedisPool.java index 6b2c80c..8e34d19 100644 --- a/src/main/java/redis/clients/jedis/JedisPool.java +++ b/src/main/java/redis/clients/jedis/JedisPool.java @@ -80,11 +80,15 @@ public class JedisPool extends Pool { } public void returnBrokenResource(final Jedis resource) { - returnBrokenResourceObject(resource); + if (resource != null) { + returnBrokenResourceObject(resource); + } } public void returnResource(final Jedis resource) { - resource.resetState(); - returnResourceObject(resource); + if (resource != null) { + resource.resetState(); + returnResourceObject(resource); + } } } diff --git a/src/main/java/redis/clients/util/Pool.java b/src/main/java/redis/clients/util/Pool.java index 09d8ebb..2b0d91f 100644 --- a/src/main/java/redis/clients/util/Pool.java +++ b/src/main/java/redis/clients/util/Pool.java @@ -54,11 +54,15 @@ public abstract class Pool { } public void returnBrokenResource(final T resource) { - returnBrokenResourceObject(resource); + if (resource != null) { + returnBrokenResourceObject(resource); + } } public void returnResource(final T resource) { - returnResourceObject(resource); + if (resource != null) { + returnResourceObject(resource); + } } public void destroy() { @@ -81,4 +85,4 @@ public abstract class Pool { throw new JedisException("Could not destroy the pool", e); } } -} \ No newline at end of file +} From 4e78b811be01b3b859433fa173c2e7ba305518bc Mon Sep 17 00:00:00 2001 From: Marcos Nils Date: Mon, 3 Mar 2014 18:54:24 -0300 Subject: [PATCH 09/16] Merge JedisSlotBasedConnectionGuaranteedConnectionHandler to JedisSlotBasedConnectionHandler --- .../redis/clients/jedis/JedisCluster.java | 2 +- ...ConnectionGuaranteedConnectionHandler.java | 68 ------------------- .../JedisSlotBasedConnectionHandler.java | 50 ++++++++++++-- 3 files changed, 47 insertions(+), 73 deletions(-) delete mode 100644 src/main/java/redis/clients/jedis/JedisSlotBasedConnectionGuaranteedConnectionHandler.java diff --git a/src/main/java/redis/clients/jedis/JedisCluster.java b/src/main/java/redis/clients/jedis/JedisCluster.java index c1a34ce..121bde8 100644 --- a/src/main/java/redis/clients/jedis/JedisCluster.java +++ b/src/main/java/redis/clients/jedis/JedisCluster.java @@ -27,7 +27,7 @@ public class JedisCluster implements JedisCommands, BasicCommands { public JedisCluster(Set jedisClusterNode, int timeout, int maxRedirections) { - this.connectionHandler = new JedisSlotBasedConnectionGuaranteedConnectionHandler( + this.connectionHandler = new JedisSlotBasedConnectionHandler( jedisClusterNode); this.timeout = timeout; this.maxRedirections = maxRedirections; diff --git a/src/main/java/redis/clients/jedis/JedisSlotBasedConnectionGuaranteedConnectionHandler.java b/src/main/java/redis/clients/jedis/JedisSlotBasedConnectionGuaranteedConnectionHandler.java deleted file mode 100644 index 0fe2cec..0000000 --- a/src/main/java/redis/clients/jedis/JedisSlotBasedConnectionGuaranteedConnectionHandler.java +++ /dev/null @@ -1,68 +0,0 @@ -package redis.clients.jedis; - -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; -import java.util.Set; - -import redis.clients.jedis.exceptions.JedisConnectionException; - -public class JedisSlotBasedConnectionGuaranteedConnectionHandler extends - JedisSlotBasedConnectionHandler { - - public JedisSlotBasedConnectionGuaranteedConnectionHandler( - Set nodes) { - super(nodes); - } - - public Jedis getConnection() { - // In antirez's redis-rb-cluster implementation, - // getRandomConnection always return valid connection (able to ping-pong) - // or exception if all connections are invalid - - List pools = getShuffledNodesPool(); - - for (JedisPool pool : pools) { - Jedis jedis = null; - try { - jedis = pool.getResource(); - - if (jedis == null) { - continue; - } - - String result = jedis.ping(); - - if (result.equalsIgnoreCase("pong")) - return jedis; - - pool.returnBrokenResource(jedis); - } catch (JedisConnectionException ex) { - if (jedis != null) { - pool.returnBrokenResource(jedis); - } - } - } - - throw new JedisConnectionException("no reachable node in cluster"); - } - - @Override - public Jedis getConnectionFromSlot(int slot) { - JedisPool connectionPool = slots.get(slot); - if (connectionPool != null) { - // It can't guaranteed to get valid connection because of node assignment - return connectionPool.getResource(); - } else { - return getConnection(); - } - } - - private List getShuffledNodesPool() { - List pools = new ArrayList(); - pools.addAll(nodes.values()); - Collections.shuffle(pools); - return pools; - } - -} diff --git a/src/main/java/redis/clients/jedis/JedisSlotBasedConnectionHandler.java b/src/main/java/redis/clients/jedis/JedisSlotBasedConnectionHandler.java index 18aa424..4cd4fc7 100644 --- a/src/main/java/redis/clients/jedis/JedisSlotBasedConnectionHandler.java +++ b/src/main/java/redis/clients/jedis/JedisSlotBasedConnectionHandler.java @@ -1,7 +1,12 @@ package redis.clients.jedis; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; import java.util.Set; +import redis.clients.jedis.exceptions.JedisConnectionException; + public class JedisSlotBasedConnectionHandler extends JedisClusterConnectionHandler { @@ -10,7 +15,35 @@ public class JedisSlotBasedConnectionHandler extends } public Jedis getConnection() { - return getRandomConnection().getResource(); + // In antirez's redis-rb-cluster implementation, + // getRandomConnection always return valid connection (able to ping-pong) + // or exception if all connections are invalid + + List pools = getShuffledNodesPool(); + + for (JedisPool pool : pools) { + Jedis jedis = null; + try { + jedis = pool.getResource(); + + if (jedis == null) { + continue; + } + + String result = jedis.ping(); + + if (result.equalsIgnoreCase("pong")) + return jedis; + + pool.returnBrokenResource(jedis); + } catch (JedisConnectionException ex) { + if (jedis != null) { + pool.returnBrokenResource(jedis); + } + } + } + + throw new JedisConnectionException("no reachable node in cluster"); } @Override @@ -21,10 +54,19 @@ public class JedisSlotBasedConnectionHandler extends @Override public Jedis getConnectionFromSlot(int slot) { JedisPool connectionPool = slots.get(slot); - if (connectionPool == null) { - connectionPool = getRandomConnection(); + if (connectionPool != null) { + // It can't guaranteed to get valid connection because of node assignment + return connectionPool.getResource(); + } else { + return getConnection(); } - return connectionPool.getResource(); + } + + private List getShuffledNodesPool() { + List pools = new ArrayList(); + pools.addAll(nodes.values()); + Collections.shuffle(pools); + return pools; } } From 62b98a3e633434e4f635d4ef1ca0076d4404df42 Mon Sep 17 00:00:00 2001 From: Jonathan Leibiusky Date: Wed, 12 Mar 2014 10:31:22 -0400 Subject: [PATCH 10/16] Add tests to check returning null to pool --- src/main/java/redis/clients/util/Pool.java | 3 +++ .../java/redis/clients/jedis/tests/JedisPoolTest.java | 10 ++++++++++ 2 files changed, 13 insertions(+) diff --git a/src/main/java/redis/clients/util/Pool.java b/src/main/java/redis/clients/util/Pool.java index 2b0d91f..659c731 100644 --- a/src/main/java/redis/clients/util/Pool.java +++ b/src/main/java/redis/clients/util/Pool.java @@ -45,6 +45,9 @@ public abstract class Pool { } public void returnResourceObject(final T resource) { + if (resource == null) { + return; + } try { internalPool.returnObject(resource); } catch (Exception e) { diff --git a/src/test/java/redis/clients/jedis/tests/JedisPoolTest.java b/src/test/java/redis/clients/jedis/tests/JedisPoolTest.java index a501024..514d3b5 100644 --- a/src/test/java/redis/clients/jedis/tests/JedisPoolTest.java +++ b/src/test/java/redis/clients/jedis/tests/JedisPoolTest.java @@ -198,4 +198,14 @@ public class JedisPoolTest extends Assert { pool.returnResource(jedis2); pool.destroy(); } + + @Test + public void returnNullObjectShouldNotFail() { + JedisPool pool = new JedisPool(new JedisPoolConfig(), hnp.getHost(), + hnp.getPort(), 2000, "foobared", 0, "my_shiny_client_name"); + + pool.returnBrokenResource(null); + pool.returnResource(null); + pool.returnResourceObject(null); + } } From e449923ec01846e7063a3ad468ab5d63fba8709b Mon Sep 17 00:00:00 2001 From: Jonathan Leibiusky Date: Wed, 12 Mar 2014 10:44:00 -0400 Subject: [PATCH 11/16] [maven-release-plugin] prepare release jedis-2.4.2 --- pom.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pom.xml b/pom.xml index a55806e..2cf1640 100644 --- a/pom.xml +++ b/pom.xml @@ -9,7 +9,7 @@ jar redis.clients jedis - 2.4.2-SNAPSHOT + 2.4.2 Jedis Jedis is a blazingly small and sane Redis java client. https://github.com/xetorthio/jedis @@ -41,7 +41,7 @@ scm:git:git@github.com:xetorthio/jedis.git scm:git:git@github.com:xetorthio/jedis.git scm:git:git@github.com:xetorthio/jedis.git - jedis-2.2.0 + jedis-2.4.2 From ec03c0940e9a40e31ecce2b6912822c8f2bec64d Mon Sep 17 00:00:00 2001 From: Jonathan Leibiusky Date: Wed, 12 Mar 2014 10:44:02 -0400 Subject: [PATCH 12/16] [maven-release-plugin] prepare for next development iteration --- pom.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pom.xml b/pom.xml index 2cf1640..1be71dd 100644 --- a/pom.xml +++ b/pom.xml @@ -9,7 +9,7 @@ jar redis.clients jedis - 2.4.2 + 2.5.0-SNAPSHOT Jedis Jedis is a blazingly small and sane Redis java client. https://github.com/xetorthio/jedis @@ -41,7 +41,7 @@ scm:git:git@github.com:xetorthio/jedis.git scm:git:git@github.com:xetorthio/jedis.git scm:git:git@github.com:xetorthio/jedis.git - jedis-2.4.2 + jedis-2.2.0 From d00e8b6444b6e4d79e8d0efa2fb20cd0fc915e69 Mon Sep 17 00:00:00 2001 From: Jonathan Leibiusky Date: Wed, 12 Mar 2014 13:13:48 -0400 Subject: [PATCH 13/16] revert back version --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 1be71dd..a55806e 100644 --- a/pom.xml +++ b/pom.xml @@ -9,7 +9,7 @@ jar redis.clients jedis - 2.5.0-SNAPSHOT + 2.4.2-SNAPSHOT Jedis Jedis is a blazingly small and sane Redis java client. https://github.com/xetorthio/jedis From 70fa35f3ba13b90d74cf98095e7525d10e1cf80a Mon Sep 17 00:00:00 2001 From: Jonathan Leibiusky Date: Wed, 12 Mar 2014 13:14:49 -0400 Subject: [PATCH 14/16] [maven-release-plugin] prepare release jedis-2.4.2 --- pom.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pom.xml b/pom.xml index a55806e..2cf1640 100644 --- a/pom.xml +++ b/pom.xml @@ -9,7 +9,7 @@ jar redis.clients jedis - 2.4.2-SNAPSHOT + 2.4.2 Jedis Jedis is a blazingly small and sane Redis java client. https://github.com/xetorthio/jedis @@ -41,7 +41,7 @@ scm:git:git@github.com:xetorthio/jedis.git scm:git:git@github.com:xetorthio/jedis.git scm:git:git@github.com:xetorthio/jedis.git - jedis-2.2.0 + jedis-2.4.2 From bcd40b4e34d367cdbcc35c66bd210283f0608ee0 Mon Sep 17 00:00:00 2001 From: Jonathan Leibiusky Date: Wed, 12 Mar 2014 13:14:51 -0400 Subject: [PATCH 15/16] [maven-release-plugin] prepare for next development iteration --- pom.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pom.xml b/pom.xml index 2cf1640..1be71dd 100644 --- a/pom.xml +++ b/pom.xml @@ -9,7 +9,7 @@ jar redis.clients jedis - 2.4.2 + 2.5.0-SNAPSHOT Jedis Jedis is a blazingly small and sane Redis java client. https://github.com/xetorthio/jedis @@ -41,7 +41,7 @@ scm:git:git@github.com:xetorthio/jedis.git scm:git:git@github.com:xetorthio/jedis.git scm:git:git@github.com:xetorthio/jedis.git - jedis-2.4.2 + jedis-2.2.0 From d7f88789eacd27b50ab01de0d26caaf3b4edc843 Mon Sep 17 00:00:00 2001 From: Jungtaek Lim Date: Sat, 22 Mar 2014 18:00:34 +0900 Subject: [PATCH 16/16] Reflect recent version to maven dependency explain --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index bbefbe1..450c574 100644 --- a/README.md +++ b/README.md @@ -48,7 +48,7 @@ Or use it as a maven dependency: redis.clients jedis - 2.2.1 + 2.4.2 jar compile