Skip to content

Commit 13b7309

Browse files
authored
Merge pull request #1957 from snicoll/gh-1953
Backport of gh-1910 to fix race condition
2 parents 9dc40d5 + 77aa60f commit 13b7309

File tree

2 files changed

+32
-15
lines changed

2 files changed

+32
-15
lines changed

src/main/java/redis/clients/jedis/JedisSentinelPool.java

Lines changed: 19 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,8 @@ public class JedisSentinelPool extends Pool<Jedis> {
3434
private volatile JedisFactory factory;
3535
private volatile HostAndPort currentHostMaster;
3636

37+
private final Object initPoolLock = new Object();
38+
3739
public JedisSentinelPool(String masterName, Set<String> sentinels,
3840
final GenericObjectPoolConfig poolConfig) {
3941
this(masterName, sentinels, poolConfig, Protocol.DEFAULT_TIMEOUT, null,
@@ -110,22 +112,24 @@ public HostAndPort getCurrentHostMaster() {
110112
}
111113

112114
private void initPool(HostAndPort master) {
113-
if (!master.equals(currentHostMaster)) {
114-
currentHostMaster = master;
115-
if (factory == null) {
116-
factory = new JedisFactory(master.getHost(), master.getPort(), connectionTimeout,
117-
soTimeout, password, database, clientName, false, null, null, null);
118-
initPool(poolConfig, factory);
119-
} else {
120-
factory.setHostAndPort(currentHostMaster);
121-
// although we clear the pool, we still have to check the
122-
// returned object
123-
// in getResource, this call only clears idle instances, not
124-
// borrowed instances
125-
internalPool.clear();
126-
}
115+
synchronized(initPoolLock){
116+
if (!master.equals(currentHostMaster)) {
117+
currentHostMaster = master;
118+
if (factory == null) {
119+
factory = new JedisFactory(master.getHost(), master.getPort(), connectionTimeout,
120+
soTimeout, password, database, clientName, false, null, null, null);
121+
initPool(poolConfig, factory);
122+
} else {
123+
factory.setHostAndPort(currentHostMaster);
124+
// although we clear the pool, we still have to check the
125+
// returned object
126+
// in getResource, this call only clears idle instances, not
127+
// borrowed instances
128+
internalPool.clear();
129+
}
127130

128-
log.info("Created JedisPool to master at " + master);
131+
log.info("Created JedisPool to master at " + master);
132+
}
129133
}
130134
}
131135

src/test/java/redis/clients/jedis/tests/JedisSentinelPoolTest.java

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,19 @@ public void setUp() throws Exception {
4242
sentinelJedis1 = new Jedis(sentinel1.getHost(), sentinel1.getPort());
4343
sentinelJedis2 = new Jedis(sentinel2.getHost(), sentinel2.getPort());
4444
}
45+
46+
@Test
47+
public void repeatedSentinelPoolInitialization() {
48+
49+
for(int i=0; i<20 ; ++i) {
50+
GenericObjectPoolConfig config = new GenericObjectPoolConfig();
51+
52+
JedisSentinelPool pool = new JedisSentinelPool(MASTER_NAME, sentinels, config, 1000,
53+
"foobared", 2);
54+
pool.getResource().close();
55+
pool.destroy();
56+
}
57+
}
4558

4659
@Test(expected = JedisConnectionException.class)
4760
public void initializeWithNotAvailableSentinelsShouldThrowException() {

0 commit comments

Comments
 (0)