diff --git a/.gitignore b/.gitignore
index 982e6b6..181df84 100644
--- a/.gitignore
+++ b/.gitignore
@@ -9,3 +9,6 @@ target/
build/
bin/
tags
+.idea
+*.aof
+*.rdb
diff --git a/Makefile b/Makefile
index 3485047..1ac2bb9 100644
--- a/Makefile
+++ b/Makefile
@@ -25,6 +25,7 @@ define REDIS3_CONF
daemonize yes
port 6381
requirepass foobared
+masterauth foobared
pidfile /tmp/redis3.pid
logfile /tmp/redis3.log
save ""
@@ -52,7 +53,7 @@ pidfile /tmp/redis5.pid
logfile /tmp/redis5.log
save ""
appendonly no
-slaveof localhost 6381
+slaveof localhost 6379
endef
define REDIS6_CONF
@@ -64,7 +65,6 @@ pidfile /tmp/redis6.pid
logfile /tmp/redis6.log
save ""
appendonly no
-slaveof localhost 6379
endef
define REDIS7_CONF
@@ -76,18 +76,7 @@ pidfile /tmp/redis7.pid
logfile /tmp/redis7.log
save ""
appendonly no
-endef
-
-define REDIS8_CONF
-daemonize yes
-port 6386
-requirepass foobared
-masterauth foobared
-pidfile /tmp/redis8.pid
-logfile /tmp/redis8.log
-save ""
-appendonly no
-slaveof localhost 6385
+slaveof localhost 6384
endef
# SENTINELS
@@ -97,7 +86,7 @@ daemonize yes
sentinel monitor mymaster 127.0.0.1 6379 1
sentinel auth-pass mymaster foobared
sentinel down-after-milliseconds mymaster 2000
-sentinel failover-timeout mymaster 180000
+sentinel failover-timeout mymaster 120000
sentinel parallel-syncs mymaster 1
pidfile /tmp/sentinel1.pid
logfile /tmp/sentinel1.log
@@ -106,11 +95,11 @@ endef
define REDIS_SENTINEL2
port 26380
daemonize yes
-sentinel monitor mymaster 127.0.0.1 6381 2
+sentinel monitor mymaster 127.0.0.1 6381 1
sentinel auth-pass mymaster foobared
sentinel down-after-milliseconds mymaster 2000
sentinel parallel-syncs mymaster 1
-sentinel failover-timeout mymaster 180000
+sentinel failover-timeout mymaster 120000
pidfile /tmp/sentinel2.pid
logfile /tmp/sentinel2.log
endef
@@ -118,25 +107,13 @@ endef
define REDIS_SENTINEL3
port 26381
daemonize yes
-sentinel monitor mymaster 127.0.0.1 6381 2
-sentinel auth-pass mymaster foobared
-sentinel down-after-milliseconds mymaster 2000
-sentinel parallel-syncs mymaster 1
-sentinel failover-timeout mymaster 180000
-pidfile /tmp/sentinel3.pid
-logfile /tmp/sentinel3.log
-endef
-
-define REDIS_SENTINEL4
-port 26382
-daemonize yes
-sentinel monitor mymasterfailover 127.0.0.1 6385 1
+sentinel monitor mymasterfailover 127.0.0.1 6384 1
sentinel auth-pass mymasterfailover foobared
sentinel down-after-milliseconds mymasterfailover 2000
-sentinel failover-timeout mymasterfailover 180000
+sentinel failover-timeout mymasterfailover 120000
sentinel parallel-syncs mymasterfailover 1
-pidfile /tmp/sentinel4.pid
-logfile /tmp/sentinel4.log
+pidfile /tmp/sentinel3.pid
+logfile /tmp/sentinel3.log
endef
# CLUSTER REDIS NODES
@@ -183,11 +160,9 @@ export REDIS4_CONF
export REDIS5_CONF
export REDIS6_CONF
export REDIS7_CONF
-export REDIS8_CONF
export REDIS_SENTINEL1
export REDIS_SENTINEL2
export REDIS_SENTINEL3
-export REDIS_SENTINEL4
export REDIS_CLUSTER_NODE1_CONF
export REDIS_CLUSTER_NODE2_CONF
export REDIS_CLUSTER_NODE3_CONF
@@ -200,14 +175,11 @@ start: cleanup
echo "$$REDIS5_CONF" | redis-server -
echo "$$REDIS6_CONF" | redis-server -
echo "$$REDIS7_CONF" | redis-server -
- echo "$$REDIS8_CONF" | redis-server -
echo "$$REDIS_SENTINEL1" > /tmp/sentinel1.conf && redis-server /tmp/sentinel1.conf --sentinel
@sleep 0.5
echo "$$REDIS_SENTINEL2" > /tmp/sentinel2.conf && redis-server /tmp/sentinel2.conf --sentinel
@sleep 0.5
echo "$$REDIS_SENTINEL3" > /tmp/sentinel3.conf && redis-server /tmp/sentinel3.conf --sentinel
- @sleep 0.5
- echo "$$REDIS_SENTINEL4" > /tmp/sentinel4.conf && redis-server /tmp/sentinel4.conf --sentinel
echo "$$REDIS_CLUSTER_NODE1_CONF" | redis-server -
echo "$$REDIS_CLUSTER_NODE2_CONF" | redis-server -
echo "$$REDIS_CLUSTER_NODE3_CONF" | redis-server -
@@ -219,24 +191,20 @@ cleanup:
stop:
kill `cat /tmp/redis1.pid`
kill `cat /tmp/redis2.pid`
- # this get's segfaulted by the tests
- kill `cat /tmp/redis3.pid` || true
- kill `cat /tmp/redis4.pid` || true
- kill `cat /tmp/redis5.pid` || true
- kill `cat /tmp/redis6.pid` || true
+ kill `cat /tmp/redis3.pid`
+ kill `cat /tmp/redis4.pid`
+ kill `cat /tmp/redis5.pid`
+ kill `cat /tmp/redis6.pid`
kill `cat /tmp/redis7.pid`
- kill `cat /tmp/redis8.pid`
kill `cat /tmp/sentinel1.pid`
kill `cat /tmp/sentinel2.pid`
kill `cat /tmp/sentinel3.pid`
- kill `cat /tmp/sentinel4.pid`
kill `cat /tmp/redis_cluster_node1.pid` || true
kill `cat /tmp/redis_cluster_node2.pid` || true
kill `cat /tmp/redis_cluster_node3.pid` || true
rm -f /tmp/sentinel1.conf
rm -f /tmp/sentinel2.conf
rm -f /tmp/sentinel3.conf
- rm -f /tmp/sentinel4.conf
rm -f /tmp/redis_cluster_node1.conf
rm -f /tmp/redis_cluster_node2.conf
rm -f /tmp/redis_cluster_node3.conf
diff --git a/pom.xml b/pom.xml
index 064af01..a55806e 100644
--- a/pom.xml
+++ b/pom.xml
@@ -9,7 +9,7 @@
jar
redis.clients
jedis
- 2.4.1-SNAPSHOT
+ 2.4.2-SNAPSHOT
Jedis
Jedis is a blazingly small and sane Redis java client.
https://github.com/xetorthio/jedis
@@ -45,8 +45,8 @@
- localhost:6379,localhost:6380,localhost:6381,localhost:6382,localhost:6383,localhost:6384,localhost:6385,localhost:6386
- localhost:26379,localhost:26380,localhost:26381,localhost:26382
+ localhost:6379,localhost:6380,localhost:6381,localhost:6382,localhost:6383,localhost:6384,localhost:6385
+ localhost:26379,localhost:26380,localhost:26381
localhost:7379,localhost:7380,localhost:7381
github
diff --git a/src/test/java/redis/clients/jedis/tests/HostAndPortUtil.java b/src/test/java/redis/clients/jedis/tests/HostAndPortUtil.java
index 491f0a3..cb7a58b 100644
--- a/src/test/java/redis/clients/jedis/tests/HostAndPortUtil.java
+++ b/src/test/java/redis/clients/jedis/tests/HostAndPortUtil.java
@@ -23,7 +23,6 @@ public class HostAndPortUtil {
sentinelHostAndPortList.add(new HostAndPort("localhost", Protocol.DEFAULT_SENTINEL_PORT));
sentinelHostAndPortList.add(new HostAndPort("localhost", Protocol.DEFAULT_SENTINEL_PORT + 1));
sentinelHostAndPortList.add(new HostAndPort("localhost", Protocol.DEFAULT_SENTINEL_PORT + 2));
- sentinelHostAndPortList.add(new HostAndPort("localhost", Protocol.DEFAULT_SENTINEL_PORT + 3));
clusterHostAndPortList.add(new HostAndPort("localhost", 7379));
clusterHostAndPortList.add(new HostAndPort("localhost", 7380));
diff --git a/src/test/java/redis/clients/jedis/tests/JedisSentinelPoolTest.java b/src/test/java/redis/clients/jedis/tests/JedisSentinelPoolTest.java
index f8a3ee2..c8df9c5 100644
--- a/src/test/java/redis/clients/jedis/tests/JedisSentinelPoolTest.java
+++ b/src/test/java/redis/clients/jedis/tests/JedisSentinelPoolTest.java
@@ -2,18 +2,17 @@ package redis.clients.jedis.tests;
import java.util.HashSet;
import java.util.Set;
-import java.util.concurrent.atomic.AtomicReference;
import org.apache.commons.pool2.impl.GenericObjectPoolConfig;
import org.junit.Before;
import org.junit.Test;
-import redis.clients.jedis.DebugParams;
import redis.clients.jedis.HostAndPort;
import redis.clients.jedis.Jedis;
-import redis.clients.jedis.JedisPubSub;
import redis.clients.jedis.JedisSentinelPool;
import redis.clients.jedis.Transaction;
+import redis.clients.jedis.exceptions.JedisConnectionException;
+import redis.clients.jedis.tests.utils.JedisSentinelTestUtil;
public class JedisSentinelPoolTest extends JedisTestBase {
private static final String MASTER_NAME = "mymaster";
@@ -22,12 +21,8 @@ public class JedisSentinelPoolTest extends JedisTestBase {
.get(2);
protected static HostAndPort slave1 = HostAndPortUtil.getRedisServers()
.get(3);
- protected static HostAndPort slave2 = HostAndPortUtil.getRedisServers()
- .get(4);
protected static HostAndPort sentinel1 = HostAndPortUtil
.getSentinelServers().get(1);
- protected static HostAndPort sentinel2 = HostAndPortUtil
- .getSentinelServers().get(2);
protected static Jedis sentinelJedis1;
@@ -36,7 +31,6 @@ public class JedisSentinelPoolTest extends JedisTestBase {
@Before
public void setUp() throws Exception {
sentinels.add(sentinel1.toString());
- sentinels.add(sentinel2.toString());
sentinelJedis1 = new Jedis(sentinel1.getHost(), sentinel1.getPort());
}
@@ -46,17 +40,47 @@ public class JedisSentinelPoolTest extends JedisTestBase {
JedisSentinelPool pool = new JedisSentinelPool(MASTER_NAME, sentinels,
new GenericObjectPoolConfig(), 1000, "foobared", 2);
- // perform failover
- doSegFaultMaster(pool);
-
- // perform failover once again
- doSegFaultMaster(pool);
+ forceFailover(pool);
+ forceFailover(pool);
// you can test failover as much as possible
- // but you need to prepare additional slave per failover
+ }
+
+ @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 jedis2 = null;
+
+ try {
+ jedis.set("hello", "jedis");
+ Transaction t = jedis.multi();
+ t.set("hello", "world");
+ pool.returnResource(jedis);
+
+ jedis2 = pool.getResource();
+
+ assertTrue(jedis == jedis2);
+ assertEquals("jedis", jedis2.get("hello"));
+ } catch (JedisConnectionException e) {
+ if (jedis2 != null) {
+ pool.returnBrokenResource(jedis2);
+ jedis2 = null;
+ }
+ } finally {
+ if (jedis2 != null)
+ pool.returnResource(jedis2);
+
+ pool.destroy();
+ }
}
- private void doSegFaultMaster(JedisSentinelPool pool)
+ private void forceFailover(JedisSentinelPool pool)
throws InterruptedException {
HostAndPort oldMaster = pool.getCurrentHostMaster();
@@ -64,14 +88,16 @@ public class JedisSentinelPoolTest extends JedisTestBase {
Jedis jedis = pool.getResource();
assertEquals("PONG", jedis.ping());
- try {
- jedis.debug(DebugParams.SEGFAULT());
- } catch (Exception e) {
- }
-
+ // It can throw JedisDataException while there's no slave to promote
+ // There's nothing we can do, so we just pass Exception to make test
+ // fail fast
+ sentinelJedis1.sentinelFailover(MASTER_NAME);
+
waitForFailover(pool, oldMaster);
+ // JedisSentinelPool recognize master but may not changed internal pool
+ // yet
Thread.sleep(100);
-
+
jedis = pool.getResource();
assertEquals("PONG", jedis.ping());
assertEquals("foobared", jedis.configGet("requirepass").get(1));
@@ -80,62 +106,15 @@ public class JedisSentinelPoolTest extends JedisTestBase {
private void waitForFailover(JedisSentinelPool pool, HostAndPort oldMaster)
throws InterruptedException {
- waitForJedisSentinelPoolRecognizeNewMaster(pool);
+ HostAndPort newMaster = JedisSentinelTestUtil
+ .waitForNewPromotedMaster(sentinelJedis1);
+
+ waitForJedisSentinelPoolRecognizeNewMaster(pool, newMaster);
}
private void waitForJedisSentinelPoolRecognizeNewMaster(
- JedisSentinelPool pool) throws InterruptedException {
-
- final AtomicReference newmaster = new AtomicReference(
- "");
-
- sentinelJedis1.psubscribe(new JedisPubSub() {
-
- @Override
- public void onMessage(String channel, String message) {
- // TODO Auto-generated method stub
-
- }
-
- @Override
- public void onPMessage(String pattern, String channel,
- String message) {
- if (channel.equals("+switch-master")) {
- newmaster.set(message);
- punsubscribe();
- }
- // TODO Auto-generated method stub
-
- }
-
- @Override
- public void onSubscribe(String channel, int subscribedChannels) {
- // TODO Auto-generated method stub
-
- }
-
- @Override
- public void onUnsubscribe(String channel, int subscribedChannels) {
- // TODO Auto-generated method stub
-
- }
-
- @Override
- public void onPUnsubscribe(String pattern, int subscribedChannels) {
- // TODO Auto-generated method stub
-
- }
-
- @Override
- public void onPSubscribe(String pattern, int subscribedChannels) {
- // TODO Auto-generated method stub
-
- }
- }, "*");
-
- String[] chunks = newmaster.get().split(" ");
- HostAndPort newMaster = new HostAndPort(chunks[3],
- Integer.parseInt(chunks[4]));
+ JedisSentinelPool pool, HostAndPort newMaster)
+ throws InterruptedException {
while (true) {
String host = pool.getCurrentHostMaster().getHost();
@@ -150,25 +129,5 @@ public class JedisSentinelPoolTest extends JedisTestBase {
Thread.sleep(100);
}
}
-
- @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();
- }
+
}
diff --git a/src/test/java/redis/clients/jedis/tests/JedisSentinelTest.java b/src/test/java/redis/clients/jedis/tests/JedisSentinelTest.java
index 4445072..822c659 100644
--- a/src/test/java/redis/clients/jedis/tests/JedisSentinelTest.java
+++ b/src/test/java/redis/clients/jedis/tests/JedisSentinelTest.java
@@ -22,15 +22,15 @@ public class JedisSentinelTest extends JedisTestBase {
protected static HostAndPort master = HostAndPortUtil.getRedisServers()
.get(0);
- protected static HostAndPort slave = HostAndPortUtil.getRedisServers().get(
- 5);
+ protected static HostAndPort slave = HostAndPortUtil.getRedisServers()
+ .get(4);
protected static HostAndPort sentinel = HostAndPortUtil
.getSentinelServers().get(0);
protected static HostAndPort sentinelForFailover = HostAndPortUtil
- .getSentinelServers().get(3);
+ .getSentinelServers().get(2);
protected static HostAndPort masterForFailover = HostAndPortUtil
- .getRedisServers().get(6);
+ .getRedisServers().get(5);
@Before
public void setup() throws InterruptedException {
@@ -50,30 +50,35 @@ public class JedisSentinelTest extends JedisTestBase {
@Test
public void sentinel() {
Jedis j = new Jedis(sentinel.getHost(), sentinel.getPort());
- List