Skip to content

Commit 4a48573

Browse files
authored
[automatic failover] Remove UnifiedJedis experimental constructor accepting MultiDbConnectionProvider (#4316)
* Remove UnifiedJedis(MultiDbConnectionProvider) experimental constructor The recommended way to create MultiDbClient is using MultiDbClient.builder(). Update all tests to use the builder pattern. Fixes #4307 * revert unintentional change in MultiDbClientBuilder
1 parent 5f00576 commit 4a48573

File tree

6 files changed

+50
-51
lines changed

6 files changed

+50
-51
lines changed

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

Lines changed: 0 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -232,18 +232,6 @@ public UnifiedJedis(ConnectionProvider provider, int maxAttempts, Duration maxTo
232232
this(new RetryableCommandExecutor(provider, maxAttempts, maxTotalRetriesDuration), provider);
233233
}
234234

235-
/**
236-
* Constructor which supports multiple cluster/database endpoints each with their own isolated connection pool.
237-
* <p>
238-
* With this Constructor users can seamlessly failover to Disaster Recovery (DR), Backup, and Active-Active cluster(s)
239-
* by using simple configuration which is passed through from Resilience4j - https://resilience4j.readme.io/docs
240-
* <p>
241-
*/
242-
@Experimental
243-
public UnifiedJedis(MultiDbConnectionProvider provider) {
244-
this(new MultiDbCommandExecutor(provider), provider);
245-
}
246-
247235
/**
248236
* The constructor to use a custom {@link CommandExecutor}.
249237
* <p>

src/test/java/redis/clients/jedis/failover/FailoverIntegrationTest.java

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
import redis.clients.jedis.EndpointConfig;
1717
import redis.clients.jedis.HostAndPorts;
1818
import redis.clients.jedis.JedisClientConfig;
19+
import redis.clients.jedis.MultiDbClient;
1920
import redis.clients.jedis.MultiDbConfig;
2021
import redis.clients.jedis.UnifiedJedis;
2122
import redis.clients.jedis.exceptions.JedisConnectionException;
@@ -58,7 +59,7 @@ public class FailoverIntegrationTest {
5859
private static String JEDIS1_ID = "";
5960
private static String JEDIS2_ID = "";
6061
private MultiDbConnectionProvider provider;
61-
private UnifiedJedis failoverClient;
62+
private MultiDbClient failoverClient;
6263

6364
@BeforeAll
6465
public static void setupAdminClients() throws IOException {
@@ -110,7 +111,7 @@ public void setup() throws IOException {
110111

111112
// Create default provider and client for most tests
112113
provider = createProvider();
113-
failoverClient = new UnifiedJedis(provider);
114+
failoverClient = MultiDbClient.builder().connectionProvider(provider).build();
114115
}
115116

116117
@AfterEach
@@ -272,7 +273,7 @@ public void testCircuitBreakerCountsEachConnectionErrorSeparately() throws IOExc
272273
.build();
273274

274275
MultiDbConnectionProvider provider = new MultiDbConnectionProvider(failoverConfig);
275-
try (UnifiedJedis client = new UnifiedJedis(provider)) {
276+
try (MultiDbClient client = MultiDbClient.builder().connectionProvider(provider).build()) {
276277
// Verify initial connection to first endpoint
277278
assertThat(getNodeId(client.info("server")), equalTo(JEDIS1_ID));
278279

@@ -321,7 +322,8 @@ public void testInflightCommandsAreRetriedAfterFailover() throws Exception {
321322
builder -> builder.retryOnFailover(true));
322323

323324
// Create a custom client with retryOnFailover enabled for this specific test
324-
try (UnifiedJedis customClient = new UnifiedJedis(customProvider)) {
325+
try (MultiDbClient customClient = MultiDbClient.builder().connectionProvider(customProvider)
326+
.build()) {
325327

326328
assertThat(getNodeId(customClient.info("server")), equalTo(JEDIS1_ID));
327329
Thread.sleep(1000);
@@ -362,7 +364,8 @@ public void testInflightCommandsAreNotRetriedAfterFailover() throws Exception {
362364
MultiDbConnectionProvider customProvider = createProvider(
363365
builder -> builder.retryOnFailover(false));
364366

365-
try (UnifiedJedis customClient = new UnifiedJedis(customProvider)) {
367+
try (MultiDbClient customClient = MultiDbClient.builder().connectionProvider(customProvider)
368+
.build()) {
366369

367370
assertThat(getNodeId(customClient.info("server")), equalTo(JEDIS1_ID));
368371
Future<List<String>> blpop = executor.submit(() -> customClient.blpop(500, "test-list-2"));

src/test/java/redis/clients/jedis/mcf/ActiveActiveLocalFailoverTest.java

Lines changed: 19 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
import redis.clients.jedis.scenario.RecommendedSettings;
2525
import redis.clients.jedis.scenario.FaultInjectionClient.TriggerActionResponse;
2626
import redis.clients.jedis.exceptions.JedisConnectionException;
27+
import redis.clients.jedis.util.ClientTestUtil;
2728

2829
import java.io.IOException;
2930
import java.time.Duration;
@@ -153,13 +154,12 @@ public void accept(DatabaseSwitchEvent e) {
153154
ensureEndpointAvailability(endpoint1.getHostAndPort(), config);
154155
ensureEndpointAvailability(endpoint2.getHostAndPort(), config);
155156

156-
// Create the connection provider
157-
MultiDbConnectionProvider provider = new MultiDbConnectionProvider(builder.build());
158157
FailoverReporter reporter = new FailoverReporter();
159-
provider.setDatabaseSwitchListener(reporter);
160-
provider.setActiveDatabase(endpoint1.getHostAndPort());
161158

162-
UnifiedJedis client = new UnifiedJedis(provider);
159+
MultiDbClient multiDbClient = MultiDbClient.builder().multiDbConfig(builder.build())
160+
.databaseSwitchListener(reporter).build();
161+
162+
multiDbClient.setActiveDatabase(endpoint1.getHostAndPort());
163163

164164
AtomicLong retryingThreadsCounter = new AtomicLong(0);
165165
AtomicLong failedCommandsAfterFailover = new AtomicLong(0);
@@ -169,33 +169,32 @@ public void accept(DatabaseSwitchEvent e) {
169169
AtomicBoolean unexpectedErrors = new AtomicBoolean(false);
170170
AtomicReference<Exception> lastException = new AtomicReference<Exception>();
171171
AtomicLong stopRunningAt = new AtomicLong();
172-
String database2Id = provider.getDatabase(endpoint2.getHostAndPort()).getCircuitBreaker()
173-
.getName();
172+
Endpoint db2Endpoint = endpoint2.getHostAndPort();
174173

175-
// Start thread that imitates an application that uses the client
174+
// Start thread that imitates an application that uses the multiDbClient
176175
RateLimiterConfig rateLimiterConfig = RateLimiterConfig.custom().limitForPeriod(100)
177176
.limitRefreshPeriod(Duration.ofSeconds(1)).timeoutDuration(Duration.ofSeconds(1)).build();
178177

179-
MultiThreadedFakeApp fakeApp = new MultiThreadedFakeApp(client, (UnifiedJedis c) -> {
178+
MultiThreadedFakeApp fakeApp = new MultiThreadedFakeApp(multiDbClient, (UnifiedJedis c) -> {
180179

181180
long threadId = Thread.currentThread().getId();
182181

183182
int attempt = 0;
184183
int maxTries = 500;
185184
int retryingDelay = 5;
186-
String currentDatabaseId = null;
185+
String currentDbKey = null;
187186
while (true) {
188187
try {
189188
if (System.currentTimeMillis() > stopRunningAt.get()) break;
190-
currentDatabaseId = provider.getDatabase().getCircuitBreaker().getName();
189+
currentDbKey = dbKey(multiDbClient.getActiveDatabaseEndpoint());
191190
Map<String, String> executionInfo = new HashMap<String, String>() {
192191
{
193192
put("threadId", String.valueOf(threadId));
194193
put("database", reporter.getCurrentDatabaseName());
195194
}
196195
};
197196

198-
client.xadd("execution_log", StreamEntryID.NEW_ENTRY, executionInfo);
197+
multiDbClient.xadd("execution_log", StreamEntryID.NEW_ENTRY, executionInfo);
199198

200199
if (attempt > 0) {
201200
log.info("Thread {} recovered after {} ms. Threads still not recovered: {}", threadId,
@@ -204,7 +203,7 @@ public void accept(DatabaseSwitchEvent e) {
204203

205204
break;
206205
} catch (JedisConnectionException e) {
207-
if (database2Id.equals(currentDatabaseId)) {
206+
if (dbKey(db2Endpoint).equals(currentDbKey)) {
208207
break;
209208
}
210209
lastException.set(e);
@@ -232,7 +231,7 @@ public void accept(DatabaseSwitchEvent e) {
232231
}
233232
if (++attempt == maxTries) throw e;
234233
} catch (Exception e) {
235-
if (database2Id.equals(currentDatabaseId)) {
234+
if (dbKey(db2Endpoint).equals(currentDbKey)) {
236235
break;
237236
}
238237
lastException.set(e);
@@ -276,6 +275,7 @@ public boolean isCompleted(Duration checkInterval, Duration delayAfter, Duration
276275
}
277276
log.info("Fake app completed");
278277

278+
MultiDbConnectionProvider provider = ClientTestUtil.getConnectionProvider(multiDbClient);
279279
ConnectionPool pool = provider.getDatabase(endpoint1.getHostAndPort()).getConnectionPool();
280280

281281
log.info("First connection pool state: active: {}, idle: {}", pool.getNumActive(),
@@ -306,7 +306,11 @@ public boolean isCompleted(Duration checkInterval, Duration delayAfter, Duration
306306
}
307307
assertFalse(unexpectedErrors.get());
308308

309-
client.close();
309+
multiDbClient.close();
310+
}
311+
312+
private String dbKey(Endpoint endpoint) {
313+
return endpoint.getHost() + ":" + endpoint.getPort();
310314
}
311315

312316
private static void ensureEndpointAvailability(HostAndPort endpoint, JedisClientConfig config) {

src/test/java/redis/clients/jedis/mcf/HealthCheckIntegrationTest.java

Lines changed: 14 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -15,10 +15,11 @@
1515
import redis.clients.jedis.EndpointConfig;
1616
import redis.clients.jedis.HostAndPorts;
1717
import redis.clients.jedis.JedisClientConfig;
18+
import redis.clients.jedis.MultiDbClient;
1819
import redis.clients.jedis.MultiDbConfig;
19-
import redis.clients.jedis.UnifiedJedis;
2020
import redis.clients.jedis.MultiDbConfig.DatabaseConfig;
2121
import redis.clients.jedis.MultiDbConfig.StrategySupplier;
22+
import redis.clients.jedis.UnifiedJedis;
2223
import redis.clients.jedis.mcf.ProbingPolicy.BuiltIn;
2324
import redis.clients.jedis.scenario.RecommendedSettings;
2425

@@ -32,8 +33,9 @@ public class HealthCheckIntegrationTest {
3233
@Test
3334
public void testDisableHealthCheck() {
3435
// No health check strategy supplier means health check is disabled
35-
MultiDbConnectionProvider customProvider = getMCCF(null);
36-
try (UnifiedJedis customClient = new UnifiedJedis(customProvider)) {
36+
MultiDbConfig multiDbConfig = getMCCF(null);
37+
try (
38+
MultiDbClient customClient = MultiDbClient.builder().multiDbConfig(multiDbConfig).build()) {
3739
// Verify that the client can connect and execute commands
3840
String result = customClient.ping();
3941
assertEquals("PONG", result);
@@ -46,8 +48,9 @@ public void testDefaultStrategySupplier() {
4648
MultiDbConfig.StrategySupplier defaultSupplier = (hostAndPort, jedisClientConfig) -> {
4749
return new PingStrategy(hostAndPort, jedisClientConfig);
4850
};
49-
MultiDbConnectionProvider customProvider = getMCCF(defaultSupplier);
50-
try (UnifiedJedis customClient = new UnifiedJedis(customProvider)) {
51+
MultiDbConfig multiDbConfig = getMCCF(defaultSupplier);
52+
try (
53+
MultiDbClient customClient = MultiDbClient.builder().multiDbConfig(multiDbConfig).build()) {
5154
// Verify that the client can connect and execute commands
5255
String result = customClient.ping();
5356
assertEquals("PONG", result);
@@ -70,15 +73,16 @@ public void testCustomStrategySupplier() {
7073
});
7174
};
7275

73-
MultiDbConnectionProvider customProvider = getMCCF(strategySupplier);
74-
try (UnifiedJedis customClient = new UnifiedJedis(customProvider)) {
76+
MultiDbConfig multiDbConfig = getMCCF(strategySupplier);
77+
try (
78+
MultiDbClient customClient = MultiDbClient.builder().multiDbConfig(multiDbConfig).build()) {
7579
// Verify that the client can connect and execute commands
7680
String result = customClient.ping();
7781
assertEquals("PONG", result);
7882
}
7983
}
8084

81-
private MultiDbConnectionProvider getMCCF(MultiDbConfig.StrategySupplier strategySupplier) {
85+
private MultiDbConfig getMCCF(MultiDbConfig.StrategySupplier strategySupplier) {
8286
Function<DatabaseConfig.Builder, DatabaseConfig.Builder> modifier = builder -> strategySupplier == null
8387
? builder.healthCheckEnabled(false)
8488
: builder.healthCheckStrategySupplier(strategySupplier);
@@ -88,13 +92,13 @@ private MultiDbConnectionProvider getMCCF(MultiDbConfig.StrategySupplier strateg
8892
.apply(MultiDbConfig.DatabaseConfig.builder(e.getHostAndPort(), clientConfig)).build())
8993
.collect(Collectors.toList());
9094

91-
MultiDbConfig mccf = new MultiDbConfig.Builder(databaseConfigs)
95+
MultiDbConfig multiDbConfig = new MultiDbConfig.Builder(databaseConfigs)
9296
.commandRetry(MultiDbConfig.RetryConfig.builder().maxAttempts(1).waitDuration(1).build())
9397
.failureDetector(MultiDbConfig.CircuitBreakerConfig.builder().slidingWindowSize(1)
9498
.failureRateThreshold(100).build())
9599
.build();
96100

97-
return new MultiDbConnectionProvider(mccf);
101+
return multiDbConfig;
98102
}
99103

100104
// ========== Probe Logic Integration Tests ==========

src/test/java/redis/clients/jedis/mcf/MultiDbConnectionProviderTest.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -121,7 +121,7 @@ public void testDatabaseSwitchListener() {
121121
isValidTest.set(true);
122122
});
123123

124-
try (UnifiedJedis jedis = new UnifiedJedis(localProvider)) {
124+
try (MultiDbClient jedis = MultiDbClient.builder().connectionProvider(localProvider).build()) {
125125

126126
// This will fail due to unable to connect and open the circuit which will trigger the post
127127
// processor
@@ -236,7 +236,7 @@ public void userCommand_firstTemporary_thenPermanent_inOrder() {
236236
.maxNumFailoverAttempts(2)
237237
.commandRetry(MultiDbConfig.RetryConfig.builder().maxAttempts(1).build()).build());
238238

239-
try (UnifiedJedis jedis = new UnifiedJedis(testProvider)) {
239+
try (MultiDbClient jedis = MultiDbClient.builder().connectionProvider(testProvider).build()) {
240240
jedis.get("foo");
241241

242242
// Disable both databases so any attempt to switch results in 'no healthy database' path
@@ -278,7 +278,7 @@ public void userCommand_connectionExceptions_thenMultipleTemporary_thenPermanent
278278
.build()) {
279279
};
280280

281-
try (UnifiedJedis jedis = new UnifiedJedis(testProvider)) {
281+
try (MultiDbClient jedis = MultiDbClient.builder().connectionProvider(testProvider).build()) {
282282
jedis.get("foo");
283283

284284
// disable most weighted database so that it will fail on initial requests

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

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,7 @@ public void pipelineWithSwitch() {
7373
getDatabaseConfigs(clientConfig, hostPortWithFailure, workingEndpoint.getHostAndPort()))
7474
.build());
7575

76-
try (UnifiedJedis client = new UnifiedJedis(provider)) {
76+
try (MultiDbClient client = MultiDbClient.builder().connectionProvider(provider).build()) {
7777
AbstractPipeline pipe = client.pipelined();
7878
pipe.set("pstr", "foobar");
7979
pipe.hset("phash", "foo", "bar");
@@ -93,7 +93,7 @@ public void transactionWithSwitch() {
9393
getDatabaseConfigs(clientConfig, hostPortWithFailure, workingEndpoint.getHostAndPort()))
9494
.build());
9595

96-
try (UnifiedJedis client = new UnifiedJedis(provider)) {
96+
try (MultiDbClient client = MultiDbClient.builder().connectionProvider(provider).build()) {
9797
AbstractTransaction tx = client.multi();
9898
tx.set("tstr", "foobar");
9999
tx.hset("thash", "foo", "bar");
@@ -125,7 +125,7 @@ public void commandFailoverUnresolvableHost() {
125125
builder.build());
126126
connectionProvider.setDatabaseSwitchListener(failoverReporter);
127127

128-
UnifiedJedis jedis = new UnifiedJedis(connectionProvider);
128+
MultiDbClient jedis = MultiDbClient.builder().connectionProvider(connectionProvider).build();
129129

130130
String key = "hash-" + System.nanoTime();
131131
log.info("Starting calls to Redis");
@@ -168,7 +168,7 @@ public void commandFailover() {
168168
builder.build());
169169
connectionProvider.setDatabaseSwitchListener(failoverReporter);
170170

171-
UnifiedJedis jedis = new UnifiedJedis(connectionProvider);
171+
MultiDbClient jedis = MultiDbClient.builder().connectionProvider(connectionProvider).build();
172172

173173
String key = "hash-" + System.nanoTime();
174174
log.info("Starting calls to Redis");
@@ -208,7 +208,7 @@ public void pipelineFailover() {
208208
builder.build());
209209
cacheProvider.setDatabaseSwitchListener(failoverReporter);
210210

211-
UnifiedJedis jedis = new UnifiedJedis(cacheProvider);
211+
MultiDbClient jedis = MultiDbClient.builder().connectionProvider(cacheProvider).build();
212212

213213
String key = "hash-" + System.nanoTime();
214214
log.info("Starting calls to Redis");
@@ -243,7 +243,7 @@ public void failoverFromAuthError() {
243243
builder.build());
244244
cacheProvider.setDatabaseSwitchListener(failoverReporter);
245245

246-
UnifiedJedis jedis = new UnifiedJedis(cacheProvider);
246+
MultiDbClient jedis = MultiDbClient.builder().connectionProvider(cacheProvider).build();
247247

248248
String key = "hash-" + System.nanoTime();
249249
log.info("Starting calls to Redis");

0 commit comments

Comments
 (0)