Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support EXECABORT Error #2598

Merged
merged 1 commit into from
Jul 20, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions src/main/java/redis/clients/jedis/Protocol.java
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ public final class Protocol {
private static final String NOSCRIPT_PREFIX = "NOSCRIPT ";
private static final String WRONGPASS_PREFIX = "WRONGPASS";
private static final String NOPERM_PREFIX = "NOPERM";
private static final String EXECABORT_PREFIX = "EXECABORT ";
sazzad16 marked this conversation as resolved.
Show resolved Hide resolved

public static final String DEFAULT_HOST = "localhost";
public static final int DEFAULT_PORT = 6379;
Expand Down Expand Up @@ -131,6 +132,8 @@ private static void processError(final RedisInputStream is) {
throw new JedisAccessControlException(message);
} else if (message.startsWith(NOPERM_PREFIX)) {
throw new JedisAccessControlException(message);
} else if (message.startsWith(EXECABORT_PREFIX)) {
throw new AbortedTransactionException(message);
}
throw new JedisDataException(message);
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package redis.clients.jedis.exceptions;

public class AbortedTransactionException extends JedisDataException {

public AbortedTransactionException(final String message) {
super(message);
}

public AbortedTransactionException(final Throwable cause) {
super(cause);
}

public AbortedTransactionException(final String message, final Throwable cause) {
super(message, cause);
}
}
28 changes: 28 additions & 0 deletions src/test/java/redis/clients/jedis/tests/ExceptionsTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertSame;

import org.junit.BeforeClass;
import org.junit.Test;
Expand All @@ -20,6 +21,33 @@ public static void prepare() {
CAUSE = new Throwable("This is a test cause.");
}

@Test
public void abortedTransaction() {
try {
throw new AbortedTransactionException(MESSAGE);
} catch (Exception e) {
assertSame(AbortedTransactionException.class, e.getClass());
assertEquals(MESSAGE, e.getMessage());
assertNull(e.getCause());
}

try {
throw new AbortedTransactionException(CAUSE);
} catch (Exception e) {
assertSame(AbortedTransactionException.class, e.getClass());
assertEquals(CAUSE, e.getCause());
assertEquals(CAUSE.toString(), e.getMessage());
}

try {
throw new AbortedTransactionException(MESSAGE, CAUSE);
} catch (Exception e) {
assertSame(AbortedTransactionException.class, e.getClass());
assertEquals(MESSAGE, e.getMessage());
assertEquals(CAUSE, e.getCause());
}
}

@Test
public void invalidURI() {
try {
Expand Down
49 changes: 43 additions & 6 deletions src/test/java/redis/clients/jedis/tests/PipeliningTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertSame;
import static org.junit.Assert.assertThat;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
Expand All @@ -22,24 +23,19 @@

import org.hamcrest.CoreMatchers;
import org.hamcrest.Matcher;
import org.junit.After;
import org.junit.Test;

import redis.clients.jedis.Jedis;
import redis.clients.jedis.Pipeline;
import redis.clients.jedis.Response;
import redis.clients.jedis.Tuple;
import redis.clients.jedis.exceptions.AbortedTransactionException;
import redis.clients.jedis.exceptions.JedisDataException;
import redis.clients.jedis.tests.commands.JedisCommandTestBase;
import redis.clients.jedis.util.SafeEncoder;

public class PipeliningTest extends JedisCommandTestBase {

@After
public void tearDown() throws Exception {
jedis.close();
}

@Test
public void pipeline() {
Pipeline p = jedis.pipelined();
Expand Down Expand Up @@ -691,6 +687,47 @@ public void testCloseableWithMulti() throws IOException {
jedis2.close();
}

@Test
public void execAbort() {
final String luaTimeLimitKey = "lua-time-limit";
final String luaTimeLimit = jedis.configGet(luaTimeLimitKey).get(1);
jedis.configSet(luaTimeLimitKey, "10");

Thread thread = new Thread(() -> {
try (Jedis blocker = createJedis()) {
blocker.eval("while true do end");
} catch (Exception ex) {
// swallow any exception
}
});

Pipeline pipe = jedis.pipelined();
pipe.incr("foo");
pipe.multi();
pipe.incr("foo");
pipe.sync();

thread.start();
try {
Thread.sleep(12); // allow Redis to be busy with the script and 'lua-time-limit' to exceed
} catch (InterruptedException ex) { }

pipe.incr("foo");
Response<List<Object>> txResp = pipe.exec();
pipe.sync();
try {
txResp.get();
} catch (Exception ex) {
assertSame(AbortedTransactionException.class, ex.getClass());
} finally {
try {
jedis.scriptKill();
} finally {
jedis.configSet(luaTimeLimitKey, luaTimeLimit);
}
}
}

private void verifyHasBothValues(String firstKey, String secondKey, String value1, String value2) {
assertFalse(firstKey.equals(secondKey));
assertTrue(firstKey.equals(value1) || firstKey.equals(value2));
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,5 @@
package redis.clients.jedis.tests.commands;

import java.util.LinkedHashMap;
import java.util.Map;

import org.junit.After;
import org.junit.Before;

Expand All @@ -29,7 +26,7 @@ public void setUp() throws Exception {

@After
public void tearDown() throws Exception {
jedis.disconnect();
jedis.close();
}

protected Jedis createJedis() {
Expand Down