Fix Pipeline NPE or sth with multi

* followings are now throwing JedisDataException: it was uncontrolled or controlled by Redis itself
** exec without multi
** discard without multi
** multi within multi
* updates unit test

actually Redis returns ERR and we can pick, but Pipeline + multi has some complex sequence
so it can just throw NPE without ERR
This commit is contained in:
Jungtaek Lim
2014-04-29 00:05:49 +09:00
parent ac53759f97
commit bbc9078c3f
2 changed files with 29 additions and 0 deletions

View File

@@ -104,12 +104,18 @@ public class Pipeline extends MultiKeyPipelineBase {
} }
public Response<String> discard() { public Response<String> discard() {
if (currentMulti == null)
throw new JedisDataException("DISCARD without MULTI");
client.discard(); client.discard();
currentMulti = null; currentMulti = null;
return getResponse(BuilderFactory.STRING); return getResponse(BuilderFactory.STRING);
} }
public Response<List<Object>> exec() { public Response<List<Object>> exec() {
if (currentMulti == null)
throw new JedisDataException("EXEC without MULTI");
client.exec(); client.exec();
Response<List<Object>> response = super.getResponse(currentMulti); Response<List<Object>> response = super.getResponse(currentMulti);
currentMulti.setResponseDependency(response); currentMulti.setResponseDependency(response);
@@ -118,6 +124,9 @@ public class Pipeline extends MultiKeyPipelineBase {
} }
public Response<String> multi() { public Response<String> multi() {
if (currentMulti != null)
throw new JedisDataException("MULTI calls can not be nested");
client.multi(); client.multi();
Response<String> response = getResponse(BuilderFactory.STRING); // Expecting Response<String> response = getResponse(BuilderFactory.STRING); // Expecting
// OK // OK

View File

@@ -272,6 +272,26 @@ public class PipeliningTest extends Assert {
assertEquals("world", r3.get()); assertEquals("world", r3.get());
} }
@Test(expected = JedisDataException.class)
public void pipelineExecShoudThrowJedisDataExceptionWhenNotInMulti() {
Pipeline pipeline = jedis.pipelined();
pipeline.exec();
}
@Test(expected = JedisDataException.class)
public void pipelineDiscardShoudThrowJedisDataExceptionWhenNotInMulti() {
Pipeline pipeline = jedis.pipelined();
pipeline.discard();
}
@Test(expected = JedisDataException.class)
public void pipelineMultiShoudThrowJedisDataExceptionWhenAlreadyInMulti() {
Pipeline pipeline = jedis.pipelined();
pipeline.multi();
pipeline.set("foo", "3");
pipeline.multi();
}
@Test @Test
public void testDiscardInPipeline() { public void testDiscardInPipeline() {
Pipeline pipeline = jedis.pipelined(); Pipeline pipeline = jedis.pipelined();