JedisPool / JedisSentinelPool resets returning object's state (watched,

multi)

* BinaryClient / BinaryJedis : added feature to reset its state
(watched, multi)
* JedisPool / JedisSentinelPool : calls new feature (reset state) when
Jedis object returns to pool
* Unit Test included
This commit is contained in:
Jungtaek Lim
2013-12-21 01:33:46 +09:00
parent 46734e646a
commit 3073f778b4
7 changed files with 116 additions and 1 deletions

View File

@@ -34,10 +34,16 @@ public class BinaryClient extends Connection {
private long db; private long db;
private boolean isInWatch;
public boolean isInMulti() { public boolean isInMulti() {
return isInMulti; return isInMulti;
} }
public boolean isInWatch() {
return isInWatch;
}
public BinaryClient(final String host) { public BinaryClient(final String host) {
super(host); super(host);
} }
@@ -447,19 +453,23 @@ public class BinaryClient extends Connection {
public void discard() { public void discard() {
sendCommand(DISCARD); sendCommand(DISCARD);
isInMulti = false; isInMulti = false;
isInWatch = false;
} }
public void exec() { public void exec() {
sendCommand(EXEC); sendCommand(EXEC);
isInMulti = false; isInMulti = false;
isInWatch = false;
} }
public void watch(final byte[]... keys) { public void watch(final byte[]... keys) {
sendCommand(WATCH, keys); sendCommand(WATCH, keys);
isInWatch = true;
} }
public void unwatch() { public void unwatch() {
sendCommand(UNWATCH); sendCommand(UNWATCH);
isInWatch = false;
} }
public void sort(final byte[] key) { public void sort(final byte[] key) {
@@ -913,6 +923,14 @@ public class BinaryClient extends Connection {
super.disconnect(); super.disconnect();
} }
public void resetState() {
if (isInMulti())
discard();
if (isInWatch())
unwatch();
}
private void sendEvalCommand(Command command, byte[] script, private void sendEvalCommand(Command command, byte[] script,
byte[] keyCount, byte[][] params) { byte[] keyCount, byte[][] params) {

View File

@@ -1710,6 +1710,11 @@ public class BinaryJedis implements BasicCommands, BinaryJedisCommands, MultiKey
client.disconnect(); client.disconnect();
} }
public void resetState() {
client.resetState();
client.getAll();
}
public String watch(final byte[]... keys) { public String watch(final byte[]... keys) {
client.watch(keys); client.watch(keys);
return client.getStatusCodeReply(); return client.getStatusCodeReply();

View File

@@ -84,6 +84,7 @@ public class JedisPool extends Pool<Jedis> {
} }
public void returnResource(final Jedis resource) { public void returnResource(final Jedis resource) {
resource.resetState();
returnResourceObject(resource); returnResourceObject(resource);
} }
} }

View File

@@ -79,6 +79,7 @@ public class JedisSentinelPool extends Pool<Jedis> {
} }
public void returnResource(final Jedis resource) { public void returnResource(final Jedis resource) {
resource.resetState();
returnResourceObject(resource); returnResourceObject(resource);
} }

View File

@@ -11,6 +11,7 @@ import redis.clients.jedis.HostAndPort;
import redis.clients.jedis.Jedis; import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool; import redis.clients.jedis.JedisPool;
import redis.clients.jedis.JedisPoolConfig; import redis.clients.jedis.JedisPoolConfig;
import redis.clients.jedis.Transaction;
import redis.clients.jedis.exceptions.JedisConnectionException; import redis.clients.jedis.exceptions.JedisConnectionException;
public class JedisPoolTest extends Assert { public class JedisPoolTest extends Assert {
@@ -176,4 +177,25 @@ public class JedisPoolTest extends Assert {
pool0.returnResource(jedis); pool0.returnResource(jedis);
pool0.destroy(); pool0.destroy();
} }
@Test
public void returnResourceShouldResetState() {
GenericObjectPoolConfig config = new GenericObjectPoolConfig();
config.setMaxTotal(1);
config.setBlockWhenExhausted(false);
JedisPool pool = new JedisPool(config, hnp.getHost(), hnp.getPort(),
2000, "foobared");
Jedis jedis = pool.getResource();
jedis.set("hello", "jedis");
Transaction t = jedis.multi();
t.set("hello", "world");
pool.returnResource(jedis);
Jedis jedis2 = pool.getResource();
assertTrue(jedis == jedis2);
assertEquals("jedis", jedis2.get("hello"));
pool.returnResource(jedis2);
pool.destroy();
}
} }

View File

@@ -11,8 +11,10 @@ import org.junit.Test;
import redis.clients.jedis.DebugParams; import redis.clients.jedis.DebugParams;
import redis.clients.jedis.HostAndPort; import redis.clients.jedis.HostAndPort;
import redis.clients.jedis.Jedis; import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;
import redis.clients.jedis.JedisPubSub; import redis.clients.jedis.JedisPubSub;
import redis.clients.jedis.JedisSentinelPool; import redis.clients.jedis.JedisSentinelPool;
import redis.clients.jedis.Transaction;
public class JedisSentinelPoolTest extends JedisTestBase { public class JedisSentinelPoolTest extends JedisTestBase {
private static final String MASTER_NAME = "mymaster"; private static final String MASTER_NAME = "mymaster";
@@ -149,4 +151,24 @@ public class JedisSentinelPoolTest extends JedisTestBase {
} }
} }
@Test
public void returnResourceShouldResetState() {
GenericObjectPoolConfig config = new GenericObjectPoolConfig();
config.setMaxTotal(1);
config.setBlockWhenExhausted(false);
JedisSentinelPool pool = new JedisSentinelPool(MASTER_NAME, sentinels,
config, 1000, "foobared", 2);
Jedis jedis = pool.getResource();
jedis.set("hello", "jedis");
Transaction t = jedis.multi();
t.set("hello", "world");
pool.returnResource(jedis);
Jedis jedis2 = pool.getResource();
assertTrue(jedis == jedis2);
assertEquals("jedis", jedis2.get("hello"));
pool.returnResource(jedis2);
pool.destroy();
}
} }

View File

@@ -12,10 +12,12 @@ import org.junit.Test;
import redis.clients.jedis.Jedis; import redis.clients.jedis.Jedis;
import redis.clients.jedis.Protocol.Keyword; import redis.clients.jedis.Protocol.Keyword;
import redis.clients.jedis.Pipeline;
import redis.clients.jedis.Response; import redis.clients.jedis.Response;
import redis.clients.jedis.Transaction; import redis.clients.jedis.Transaction;
import redis.clients.jedis.TransactionBlock; import redis.clients.jedis.TransactionBlock;
import redis.clients.jedis.exceptions.JedisDataException; import redis.clients.jedis.exceptions.JedisDataException;
import redis.clients.jedis.exceptions.JedisException;
public class TransactionCommandsTest extends JedisCommandTestBase { public class TransactionCommandsTest extends JedisCommandTestBase {
final byte[] bfoo = { 0x01, 0x02, 0x03, 0x04 }; final byte[] bfoo = { 0x01, 0x02, 0x03, 0x04 };
@@ -294,4 +296,48 @@ public class TransactionCommandsTest extends JedisCommandTestBase {
assertNull(results); assertNull(results);
} }
@Test
public void testResetStateWhenInMulti() {
jedis.auth("foobared");
Transaction t = jedis.multi();
t.set("foooo", "barrr");
jedis.resetState();
assertEquals(null, jedis.get("foooo"));
}
@Test
public void testResetStateWhenInMultiWithinPipeline() {
jedis.auth("foobared");
Pipeline p = jedis.pipelined();
p.multi();
p.set("foooo", "barrr");
jedis.resetState();
assertEquals(null, jedis.get("foooo"));
}
@Test
public void testResetStateWhenInWatch() {
jedis.watch("mykey", "somekey");
// state reset : unwatch
jedis.resetState();
Transaction t = jedis.multi();
nj.connect();
nj.auth("foobared");
nj.set("mykey", "bar");
nj.disconnect();
t.set("mykey", "foo");
List<Object> resp = t.exec();
assertNotNull(resp);
assertEquals(1, resp.size());
assertEquals("foo", jedis.get("mykey"));
}
} }