Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 25acc8d

Browse files
authored
Stop connection fetching before sync/exec (#3756)
in multi cluster failover mode
1 parent 3dfa82d commit 25acc8d

File tree

7 files changed

+57
-13
lines changed

7 files changed

+57
-13
lines changed

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

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,10 @@ protected AbstractTransaction() {
99
super(new CommandObjects());
1010
}
1111

12+
protected AbstractTransaction(CommandObjects commandObjects) {
13+
super(commandObjects);
14+
}
15+
1216
public abstract void multi();
1317

1418
/**

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

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -40,8 +40,7 @@ public final class MultiClusterClientConfig {
4040
private static final float CIRCUIT_BREAKER_SLOW_CALL_RATE_THRESHOLD_DEFAULT = 100.0f; // measured as percentage
4141
private static final List<Class> CIRCUIT_BREAKER_INCLUDED_EXCEPTIONS_DEFAULT = Arrays.asList(JedisConnectionException.class);
4242

43-
private static final List<Class<? extends Throwable>> FALLBACK_EXCEPTIONS_DEFAULT =
44-
Arrays.asList(CallNotPermittedException.class, JedisConnectionException.class);
43+
private static final List<Class<? extends Throwable>> FALLBACK_EXCEPTIONS_DEFAULT = Arrays.asList(CallNotPermittedException.class);
4544

4645
private final ClusterConfig[] clusterConfigs;
4746

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

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,4 +9,8 @@ public abstract class TransactionBase extends AbstractTransaction {
99
protected TransactionBase() {
1010
super();
1111
}
12+
13+
protected TransactionBase(CommandObjects commandObjects) {
14+
super(commandObjects);
15+
}
1216
}

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4849,7 +4849,7 @@ public PipelineBase pipelined() {
48494849
if (provider == null) {
48504850
throw new IllegalStateException("It is not allowed to create Pipeline from this " + getClass());
48514851
} else if (provider instanceof MultiClusterPooledConnectionProvider) {
4852-
return new MultiClusterPipeline((MultiClusterPooledConnectionProvider) provider);
4852+
return new MultiClusterPipeline((MultiClusterPooledConnectionProvider) provider, commandObjects);
48534853
} else {
48544854
return new Pipeline(provider.getConnection(), true);
48554855
}
@@ -4859,7 +4859,7 @@ public AbstractTransaction multi() {
48594859
if (provider == null) {
48604860
throw new IllegalStateException("It is not allowed to create Pipeline from this " + getClass());
48614861
} else if (provider instanceof MultiClusterPooledConnectionProvider) {
4862-
return new MultiClusterTransaction((MultiClusterPooledConnectionProvider) provider);
4862+
return new MultiClusterTransaction((MultiClusterPooledConnectionProvider) provider, true, commandObjects);
48634863
} else {
48644864
return new Transaction(provider.getConnection(), true, true);
48654865
}

src/main/java/redis/clients/jedis/mcf/MultiClusterPipeline.java

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ public class MultiClusterPipeline extends PipelineBase implements Closeable {
2020
private final CircuitBreakerFailoverConnectionProvider failoverProvider;
2121
private final Queue<KeyValue<CommandArguments, Response<?>>> commands = new LinkedList<>();
2222

23+
@Deprecated
2324
public MultiClusterPipeline(MultiClusterPooledConnectionProvider pooledProvider) {
2425
super(new CommandObjects());
2526

@@ -31,6 +32,11 @@ public MultiClusterPipeline(MultiClusterPooledConnectionProvider pooledProvider)
3132
}
3233
}
3334

35+
public MultiClusterPipeline(MultiClusterPooledConnectionProvider pooledProvider, CommandObjects commandObjects) {
36+
super(commandObjects);
37+
this.failoverProvider = new CircuitBreakerFailoverConnectionProvider(pooledProvider);
38+
}
39+
3440
@Override
3541
protected final <T> Response<T> appendCommand(CommandObject<T> commandObject) {
3642
CommandArguments args = commandObject.getArguments();

src/main/java/redis/clients/jedis/mcf/MultiClusterTransaction.java

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ public class MultiClusterTransaction extends TransactionBase {
3838
* called with this object.
3939
* @param provider
4040
*/
41+
@Deprecated
4142
public MultiClusterTransaction(MultiClusterPooledConnectionProvider provider) {
4243
this(provider, true);
4344
}
@@ -49,6 +50,7 @@ public MultiClusterTransaction(MultiClusterPooledConnectionProvider provider) {
4950
* @param provider
5051
* @param doMulti {@code false} should be set to enable manual WATCH, UNWATCH and MULTI
5152
*/
53+
@Deprecated
5254
public MultiClusterTransaction(MultiClusterPooledConnectionProvider provider, boolean doMulti) {
5355
this.failoverProvider = new CircuitBreakerFailoverConnectionProvider(provider);
5456

@@ -60,6 +62,21 @@ public MultiClusterTransaction(MultiClusterPooledConnectionProvider provider, bo
6062
if (doMulti) multi();
6163
}
6264

65+
/**
66+
* A user wanting to WATCH/UNWATCH keys followed by a call to MULTI ({@link #multi()}) it should
67+
* be {@code doMulti=false}.
68+
*
69+
* @param provider
70+
* @param doMulti {@code false} should be set to enable manual WATCH, UNWATCH and MULTI
71+
* @param commandObjects command objects
72+
*/
73+
public MultiClusterTransaction(MultiClusterPooledConnectionProvider provider, boolean doMulti, CommandObjects commandObjects) {
74+
super(commandObjects);
75+
this.failoverProvider = new CircuitBreakerFailoverConnectionProvider(provider);
76+
77+
if (doMulti) multi();
78+
}
79+
6380
@Override
6481
public final void multi() {
6582
appendCommand(new CommandObject<>(new CommandArguments(MULTI), NO_OP_BUILDER));

src/test/java/redis/clients/jedis/misc/AutomaticFailoverTest.java

Lines changed: 23 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
import redis.clients.jedis.MultiClusterClientConfig;
2727
import redis.clients.jedis.UnifiedJedis;
2828
import redis.clients.jedis.exceptions.JedisAccessControlException;
29+
import redis.clients.jedis.exceptions.JedisConnectionException;
2930
import redis.clients.jedis.providers.MultiClusterPooledConnectionProvider;
3031
import redis.clients.jedis.util.IOUtils;
3132

@@ -68,7 +69,7 @@ public void pipelineWithSwitch() {
6869
AbstractPipeline pipe = client.pipelined();
6970
pipe.set("pstr", "foobar");
7071
pipe.hset("phash", "foo", "bar");
71-
//provider.incrementActiveMultiClusterIndex();
72+
provider.incrementActiveMultiClusterIndex();
7273
pipe.sync();
7374
}
7475

@@ -85,7 +86,7 @@ public void transactionWithSwitch() {
8586
AbstractTransaction tx = client.multi();
8687
tx.set("tstr", "foobar");
8788
tx.hset("thash", "foo", "bar");
88-
//provider.incrementActiveMultiClusterIndex();
89+
provider.incrementActiveMultiClusterIndex();
8990
assertEquals(Arrays.asList("OK", Long.valueOf(1L)), tx.exec());
9091
}
9192

@@ -109,9 +110,19 @@ public void commandFailover() {
109110

110111
UnifiedJedis jedis = new UnifiedJedis(cacheProvider);
111112

112-
assertFalse(failoverReporter.failedOver);
113-
log.info("Starting calls to Redis");
114113
String key = "hash-" + System.nanoTime();
114+
log.info("Starting calls to Redis");
115+
assertFalse(failoverReporter.failedOver);
116+
for (int attempt = 0; attempt < 10; attempt++) {
117+
try {
118+
jedis.hset(key, "f1", "v1");
119+
} catch (JedisConnectionException jce) {
120+
//
121+
}
122+
assertFalse(failoverReporter.failedOver);
123+
}
124+
125+
// should failover now
115126
jedis.hset(key, "f1", "v1");
116127
assertTrue(failoverReporter.failedOver);
117128

@@ -129,19 +140,22 @@ public void pipelineFailover() {
129140
MultiClusterClientConfig.Builder builder = new MultiClusterClientConfig.Builder(
130141
getClusterConfigs(clientConfig, hostPort_1, hostPort_2))
131142
.circuitBreakerSlidingWindowMinCalls(slidingWindowMinCalls)
132-
.circuitBreakerSlidingWindowSize(slidingWindowSize);
143+
.circuitBreakerSlidingWindowSize(slidingWindowSize)
144+
.fallbackExceptionList(Arrays.asList(JedisConnectionException.class));
133145

134146
RedisFailoverReporter failoverReporter = new RedisFailoverReporter();
135147
MultiClusterPooledConnectionProvider cacheProvider = new MultiClusterPooledConnectionProvider(builder.build());
136148
cacheProvider.setClusterFailoverPostProcessor(failoverReporter);
137149

138150
UnifiedJedis jedis = new UnifiedJedis(cacheProvider);
139151

140-
assertFalse(failoverReporter.failedOver);
152+
String key = "hash-" + System.nanoTime();
141153
log.info("Starting calls to Redis");
154+
assertFalse(failoverReporter.failedOver);
142155
AbstractPipeline pipe = jedis.pipelined();
143-
String key = "hash-" + System.nanoTime();
156+
assertFalse(failoverReporter.failedOver);
144157
pipe.hset(key, "f1", "v1");
158+
assertFalse(failoverReporter.failedOver);
145159
pipe.sync();
146160
assertTrue(failoverReporter.failedOver);
147161

@@ -168,9 +182,9 @@ public void failoverFromAuthError() {
168182

169183
UnifiedJedis jedis = new UnifiedJedis(cacheProvider);
170184

171-
assertFalse(failoverReporter.failedOver);
172-
log.info("Starting calls to Redis");
173185
String key = "hash-" + System.nanoTime();
186+
log.info("Starting calls to Redis");
187+
assertFalse(failoverReporter.failedOver);
174188
jedis.hset(key, "f1", "v1");
175189
assertTrue(failoverReporter.failedOver);
176190

0 commit comments

Comments
 (0)