Skip to content

Commit 607c66d

Browse files
committed
- fix failing scenario test
- downgrade logback version for slf4j compatibility - increase timeouts for faultInjector
1 parent 405101e commit 607c66d

File tree

4 files changed

+53
-41
lines changed

4 files changed

+53
-41
lines changed

pom.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -143,7 +143,7 @@
143143
<dependency>
144144
<groupId>ch.qos.logback</groupId>
145145
<artifactId>logback-classic</artifactId>
146-
<version>1.3.15</version>
146+
<version>1.2.12</version>
147147
<scope>test</scope>
148148
</dependency>
149149
<dependency>

src/main/java/redis/clients/jedis/providers/MultiClusterPooledConnectionProvider.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -650,6 +650,7 @@ public static class Cluster {
650650

651651
// Grace period tracking
652652
private volatile long gracePeriodEndsAt = 0;
653+
private final Logger log = LoggerFactory.getLogger(getClass());
653654

654655
public Cluster(ConnectionPool connectionPool, Retry retry, CircuitBreaker circuitBreaker, float weight,
655656
MultiClusterClientConfig multiClusterClientConfig) {
@@ -693,6 +694,7 @@ public float getWeight() {
693694

694695
public boolean isCBForcedOpen() {
695696
if (circuitBreaker.getState() == State.FORCED_OPEN && !isInGracePeriod()) {
697+
log.info("Transitioning circuit breaker from FORCED_OPEN to CLOSED state due to end of grace period!");
696698
circuitBreaker.transitionToClosedState();
697699
}
698700
return circuitBreaker.getState() == CircuitBreaker.State.FORCED_OPEN;

src/test/java/redis/clients/jedis/scenario/ActiveActiveFailoverTest.java

Lines changed: 48 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -8,11 +8,11 @@
88
import org.slf4j.Logger;
99
import org.slf4j.LoggerFactory;
1010
import redis.clients.jedis.*;
11+
import redis.clients.jedis.MultiClusterClientConfig.ClusterConfig;
1112
import redis.clients.jedis.providers.MultiClusterPooledConnectionProvider;
1213
import redis.clients.jedis.exceptions.JedisConnectionException;
1314

1415
import java.io.IOException;
15-
import java.time.Duration;
1616
import java.time.Instant;
1717
import java.util.HashMap;
1818
import java.util.Map;
@@ -25,10 +25,7 @@
2525
import static org.junit.jupiter.api.Assertions.fail;
2626
import static org.junit.jupiter.api.Assumptions.assumeTrue;
2727

28-
@Tags({
29-
@Tag("failover"),
30-
@Tag("scenario")
31-
})
28+
@Tags({ @Tag("failover"), @Tag("scenario") })
3229
public class ActiveActiveFailoverTest {
3330
private static final Logger log = LoggerFactory.getLogger(ActiveActiveFailoverTest.class);
3431

@@ -52,13 +49,13 @@ public void testFailover() {
5249
MultiClusterClientConfig.ClusterConfig[] clusterConfig = new MultiClusterClientConfig.ClusterConfig[2];
5350

5451
JedisClientConfig config = endpoint.getClientConfigBuilder()
55-
.socketTimeoutMillis(RecommendedSettings.DEFAULT_TIMEOUT_MS)
56-
.connectionTimeoutMillis(RecommendedSettings.DEFAULT_TIMEOUT_MS).build();
52+
.socketTimeoutMillis(RecommendedSettings.DEFAULT_TIMEOUT_MS)
53+
.connectionTimeoutMillis(RecommendedSettings.DEFAULT_TIMEOUT_MS).build();
5754

58-
clusterConfig[0] = new MultiClusterClientConfig.ClusterConfig(endpoint.getHostAndPort(0),
59-
config, RecommendedSettings.poolConfig);
60-
clusterConfig[1] = new MultiClusterClientConfig.ClusterConfig(endpoint.getHostAndPort(1),
61-
config, RecommendedSettings.poolConfig);
55+
clusterConfig[0] = ClusterConfig.builder(endpoint.getHostAndPort(0), config)
56+
.connectionPoolConfig(RecommendedSettings.poolConfig).weight(1.0f).build();
57+
clusterConfig[1] = ClusterConfig.builder(endpoint.getHostAndPort(1), config)
58+
.connectionPoolConfig(RecommendedSettings.poolConfig).weight(0.5f).build();
6259

6360
MultiClusterClientConfig.Builder builder = new MultiClusterClientConfig.Builder(clusterConfig);
6461

@@ -67,6 +64,10 @@ public void testFailover() {
6764
builder.circuitBreakerSlidingWindowMinCalls(1);
6865
builder.circuitBreakerFailureRateThreshold(10.0f); // percentage of failures to trigger circuit breaker
6966

67+
builder.failbackSupported(true);
68+
builder.failbackCheckInterval(1000);
69+
builder.gracePeriod(10000);
70+
7071
builder.retryWaitDuration(10);
7172
builder.retryMaxAttempts(1);
7273
builder.retryWaitDurationExponentialBackoffMultiplier(1);
@@ -79,24 +80,30 @@ class FailoverReporter implements Consumer<String> {
7980

8081
Instant failoverAt = null;
8182

83+
boolean failbackHappened = false;
84+
85+
Instant failbackAt = null;
86+
8287
public String getCurrentClusterName() {
8388
return currentClusterName;
8489
}
8590

8691
@Override
8792
public void accept(String clusterName) {
8893
this.currentClusterName = clusterName;
89-
log.info(
90-
"\n\n====FailoverEvent=== \nJedis failover to cluster: {}\n====FailoverEvent===\n\n",
91-
clusterName);
92-
93-
failoverHappened = true;
94-
failoverAt = Instant.now();
94+
log.info("\n\n====FailoverEvent=== \nJedis failover to cluster: {}\n====FailoverEvent===\n\n", clusterName);
95+
96+
if (failoverHappened) {
97+
failbackHappened = true;
98+
failbackAt = Instant.now();
99+
} else {
100+
failoverHappened = true;
101+
failoverAt = Instant.now();
102+
}
95103
}
96104
}
97105

98-
MultiClusterPooledConnectionProvider provider = new MultiClusterPooledConnectionProvider(
99-
builder.build());
106+
MultiClusterPooledConnectionProvider provider = new MultiClusterPooledConnectionProvider(builder.build());
100107
FailoverReporter reporter = new FailoverReporter();
101108
provider.setClusterFailoverPostProcessor(reporter);
102109
provider.setActiveCluster(endpoint.getHostAndPort(0));
@@ -117,15 +124,17 @@ public void accept(String clusterName) {
117124
int retryingDelay = 5;
118125
while (true) {
119126
try {
120-
Map<String, String> executionInfo = new HashMap<String, String>() {{
121-
put("threadId", String.valueOf(threadId));
122-
put("cluster", reporter.getCurrentClusterName());
123-
}};
127+
Map<String, String> executionInfo = new HashMap<String, String>() {
128+
{
129+
put("threadId", String.valueOf(threadId));
130+
put("cluster", reporter.getCurrentClusterName());
131+
}
132+
};
124133
client.xadd("execution_log", StreamEntryID.NEW_ENTRY, executionInfo);
125134

126135
if (attempt > 0) {
127136
log.info("Thread {} recovered after {} ms. Threads still not recovered: {}", threadId,
128-
attempt * retryingDelay, retryingThreadsCounter.decrementAndGet());
137+
attempt * retryingDelay, retryingThreadsCounter.decrementAndGet());
129138
}
130139

131140
break;
@@ -134,15 +143,13 @@ public void accept(String clusterName) {
134143
if (reporter.failoverHappened) {
135144
long failedCommands = failedCommandsAfterFailover.incrementAndGet();
136145
lastFailedCommandAt.set(Instant.now());
137-
log.warn(
138-
"Thread {} failed to execute command after failover. Failed commands after failover: {}",
139-
threadId, failedCommands);
146+
log.warn("Thread {} failed to execute command after failover. Failed commands after failover: {}", threadId,
147+
failedCommands);
140148
}
141149

142150
if (attempt == 0) {
143151
long failedThreads = retryingThreadsCounter.incrementAndGet();
144-
log.warn("Thread {} failed to execute command. Failed threads: {}", threadId,
145-
failedThreads);
152+
log.warn("Thread {} failed to execute command. Failed threads: {}", threadId, failedThreads);
146153
}
147154
try {
148155
Thread.sleep(retryingDelay);
@@ -153,20 +160,21 @@ public void accept(String clusterName) {
153160
}
154161
}
155162
return true;
156-
}, 18);
163+
}, 4);
157164
fakeApp.setKeepExecutingForSeconds(30);
158165
Thread t = new Thread(fakeApp);
159166
t.start();
160167

161168
HashMap<String, Object> params = new HashMap<>();
162169
params.put("bdb_id", endpoint.getBdbId());
163-
params.put("rlutil_command", "pause_bdb");
170+
params.put("actions",
171+
"[{\"type\":\"execute_rlutil_command\",\"params\":{\"rlutil_command\":\"pause_bdb\"}},{\"type\":\"wait\",\"params\":{\"wait_time\":\"15\"}},{\"type\":\"execute_rlutil_command\",\"params\":{\"rlutil_command\":\"resume_bdb\"}}]");
164172

165173
FaultInjectionClient.TriggerActionResponse actionResponse = null;
166174

167175
try {
168-
log.info("Triggering bdb_pause");
169-
actionResponse = faultClient.triggerAction("execute_rlutil_command", params);
176+
log.info("Triggering bdb_pause + wait 15 seconds + bdb_resume");
177+
actionResponse = faultClient.triggerAction("sequence_of_actions", params);
170178
} catch (IOException e) {
171179
fail("Fault Injection Server error:" + e.getMessage());
172180
}
@@ -182,15 +190,17 @@ public void accept(String clusterName) {
182190

183191
ConnectionPool pool = provider.getCluster(endpoint.getHostAndPort(0)).getConnectionPool();
184192

185-
log.info("First connection pool state: active: {}, idle: {}", pool.getNumActive(),
186-
pool.getNumIdle());
187-
log.info("Full failover time: {} s",
188-
Duration.between(reporter.failoverAt, lastFailedCommandAt.get()).getSeconds());
193+
log.info("First connection pool state: active: {}, idle: {}", pool.getNumActive(), pool.getNumIdle());
194+
log.info("Failover happened at: {}", reporter.failoverAt);
195+
log.info("Failback happened at: {}", reporter.failbackAt);
196+
log.info("Last failed command at: {}", lastFailedCommandAt.get());
189197

190198
assertEquals(0, pool.getNumActive());
191199
assertTrue(fakeApp.capturedExceptions().isEmpty());
200+
assertTrue(reporter.failoverHappened);
201+
assertTrue(reporter.failbackHappened);
192202

193203
client.close();
194204
}
195205

196-
}
206+
}

src/test/java/redis/clients/jedis/scenario/FaultInjectionClient.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -89,8 +89,8 @@ public boolean isCompleted(Duration checkInterval, Duration delayAfter, Duration
8989

9090
private static CloseableHttpClient getHttpClient() {
9191
RequestConfig requestConfig = RequestConfig.custom()
92-
.setConnectionRequestTimeout(5000, TimeUnit.MILLISECONDS)
93-
.setResponseTimeout(5000, TimeUnit.MILLISECONDS).build();
92+
.setConnectionRequestTimeout(10000, TimeUnit.MILLISECONDS)
93+
.setResponseTimeout(10000, TimeUnit.MILLISECONDS).build();
9494

9595
return HttpClientBuilder.create()
9696
.setDefaultRequestConfig(requestConfig).build();

0 commit comments

Comments
 (0)