12
12
import redis .clients .jedis .exceptions .JedisConnectionException ;
13
13
import redis .clients .jedis .exceptions .JedisValidationException ;
14
14
import redis .clients .jedis .mcf .ConnectionFailoverException ;
15
+ import redis .clients .jedis .mcf .EchoStrategy ;
16
+ import redis .clients .jedis .mcf .HealthCheckStrategy ;
15
17
16
18
/**
17
19
* @author Allen Terleto (aterleto)
31
33
@ Experimental
32
34
public final class MultiClusterClientConfig {
33
35
36
+ /**
37
+ * Interface for creating HealthCheckStrategy instances for specific endpoints
38
+ */
39
+ public static interface StrategySupplier {
40
+ /**
41
+ * Creates a HealthCheckStrategy for the given endpoint.
42
+ * @param hostAndPort the endpoint to create a strategy for
43
+ * @param jedisClientConfig the client configuration, may be null for implementations that don't need it
44
+ * @return a HealthCheckStrategy instance
45
+ */
46
+ HealthCheckStrategy get (HostAndPort hostAndPort , JedisClientConfig jedisClientConfig );
47
+ }
48
+
34
49
private static final int RETRY_MAX_ATTEMPTS_DEFAULT = 3 ;
35
50
private static final int RETRY_WAIT_DURATION_DEFAULT = 500 ; // measured in milliseconds
36
51
private static final int RETRY_WAIT_DURATION_EXPONENTIAL_BACKOFF_MULTIPLIER_DEFAULT = 2 ;
@@ -129,6 +144,14 @@ public final class MultiClusterClientConfig {
129
144
130
145
private List <Class <? extends Throwable >> fallbackExceptionList ;
131
146
147
+ //////////// Failover Config ////////////
148
+
149
+ /** Whether to retry failed commands during failover */
150
+ private boolean retryOnFailover = false ;
151
+
152
+ /** Whether failback is enabled */
153
+ private boolean failback = false ;
154
+
132
155
public MultiClusterClientConfig (ClusterConfig [] clusterConfigs ) {
133
156
this .clusterConfigs = clusterConfigs ;
134
157
}
@@ -193,13 +216,23 @@ public List<Class<? extends Throwable>> getFallbackExceptionList() {
193
216
return fallbackExceptionList ;
194
217
}
195
218
219
+ public boolean isRetryOnFailover () {
220
+ return retryOnFailover ;
221
+ }
222
+
223
+ public boolean isFailback () {
224
+ return failback ;
225
+ }
226
+
196
227
public static class ClusterConfig {
197
228
198
- private int priority ;
199
229
private HostAndPort hostAndPort ;
200
230
private JedisClientConfig clientConfig ;
201
231
private GenericObjectPoolConfig <Connection > connectionPoolConfig ;
202
232
233
+ private float weight = 1.0f ;
234
+ private StrategySupplier healthCheckStrategySupplier ;
235
+
203
236
public ClusterConfig (HostAndPort hostAndPort , JedisClientConfig clientConfig ) {
204
237
this .hostAndPort = hostAndPort ;
205
238
this .clientConfig = clientConfig ;
@@ -212,25 +245,92 @@ public ClusterConfig(HostAndPort hostAndPort, JedisClientConfig clientConfig,
212
245
this .connectionPoolConfig = connectionPoolConfig ;
213
246
}
214
247
215
- public int getPriority ( ) {
216
- return priority ;
217
- }
218
-
219
- private void setPriority ( int priority ) {
220
- this .priority = priority ;
248
+ private ClusterConfig ( Builder builder ) {
249
+ this . hostAndPort = builder . hostAndPort ;
250
+ this . clientConfig = builder . clientConfig ;
251
+ this . connectionPoolConfig = builder . connectionPoolConfig ;
252
+ this . weight = builder . weight ;
253
+ this .healthCheckStrategySupplier = builder . healthCheckStrategySupplier ;
221
254
}
222
255
223
256
public HostAndPort getHostAndPort () {
224
257
return hostAndPort ;
225
258
}
226
259
260
+ public static Builder builder (HostAndPort hostAndPort , JedisClientConfig clientConfig ) {
261
+ return new Builder (hostAndPort , clientConfig );
262
+ }
263
+
227
264
public JedisClientConfig getJedisClientConfig () {
228
265
return clientConfig ;
229
266
}
230
267
231
268
public GenericObjectPoolConfig <Connection > getConnectionPoolConfig () {
232
269
return connectionPoolConfig ;
233
270
}
271
+
272
+ public float getWeight () {
273
+ return weight ;
274
+ }
275
+
276
+ public StrategySupplier getHealthCheckStrategySupplier () {
277
+ return healthCheckStrategySupplier ;
278
+ }
279
+
280
+ public static class Builder {
281
+ private HostAndPort hostAndPort ;
282
+ private JedisClientConfig clientConfig ;
283
+ private GenericObjectPoolConfig <Connection > connectionPoolConfig ;
284
+
285
+ private float weight = 1.0f ;
286
+ private StrategySupplier healthCheckStrategySupplier = EchoStrategy .DEFAULT ;
287
+ private boolean healthCheckEnabled = true ;
288
+
289
+ public Builder (HostAndPort hostAndPort , JedisClientConfig clientConfig ) {
290
+ this .hostAndPort = hostAndPort ;
291
+ this .clientConfig = clientConfig ;
292
+ }
293
+
294
+ public Builder connectionPoolConfig (GenericObjectPoolConfig <Connection > connectionPoolConfig ) {
295
+ this .connectionPoolConfig = connectionPoolConfig ;
296
+ return this ;
297
+ }
298
+
299
+ public Builder weight (float weight ) {
300
+ this .weight = weight ;
301
+ return this ;
302
+ }
303
+
304
+ public Builder healthCheckStrategySupplier (StrategySupplier healthCheckStrategySupplier ) {
305
+ if (healthCheckStrategySupplier == null ) {
306
+ throw new IllegalArgumentException ("healthCheckStrategySupplier must not be null" );
307
+ }
308
+ this .healthCheckStrategySupplier = healthCheckStrategySupplier ;
309
+ return this ;
310
+ }
311
+
312
+ public Builder healthCheckStrategy (HealthCheckStrategy healthCheckStrategy ) {
313
+ if (healthCheckStrategy == null ) {
314
+ throw new IllegalArgumentException ("healthCheckStrategy must not be null" );
315
+ }
316
+ this .healthCheckStrategySupplier = (hostAndPort , jedisClientConfig ) -> healthCheckStrategy ;
317
+ return this ;
318
+ }
319
+
320
+ public Builder healthCheckEnabled (boolean healthCheckEnabled ) {
321
+ this .healthCheckEnabled = healthCheckEnabled ;
322
+ if (!healthCheckEnabled ) {
323
+ this .healthCheckStrategySupplier = null ;
324
+ } else if (healthCheckStrategySupplier == null ) {
325
+ this .healthCheckStrategySupplier = EchoStrategy .DEFAULT ;
326
+ }
327
+ return this ;
328
+ }
329
+
330
+ public ClusterConfig build () {
331
+ return new ClusterConfig (this );
332
+ }
333
+ }
234
334
}
235
335
236
336
public static class Builder {
@@ -253,14 +353,14 @@ public static class Builder {
253
353
private List <Class > circuitBreakerIgnoreExceptionList = null ;
254
354
private List <Class <? extends Throwable >> fallbackExceptionList = FALLBACK_EXCEPTIONS_DEFAULT ;
255
355
356
+ private boolean retryOnFailover = false ;
357
+ private boolean failback = false ;
358
+
256
359
public Builder (ClusterConfig [] clusterConfigs ) {
257
360
258
361
if (clusterConfigs == null || clusterConfigs .length < 1 ) throw new JedisValidationException (
259
362
"ClusterClientConfigs are required for MultiClusterPooledConnectionProvider" );
260
363
261
- for (int i = 0 ; i < clusterConfigs .length ; i ++)
262
- clusterConfigs [i ].setPriority (i + 1 );
263
-
264
364
this .clusterConfigs = clusterConfigs ;
265
365
}
266
366
@@ -348,6 +448,16 @@ public Builder fallbackExceptionList(List<Class<? extends Throwable>> fallbackEx
348
448
return this ;
349
449
}
350
450
451
+ public Builder retryOnFailover (boolean retryOnFailover ) {
452
+ this .retryOnFailover = retryOnFailover ;
453
+ return this ;
454
+ }
455
+
456
+ public Builder failback (boolean failback ) {
457
+ this .failback = failback ;
458
+ return this ;
459
+ }
460
+
351
461
public MultiClusterClientConfig build () {
352
462
MultiClusterClientConfig config = new MultiClusterClientConfig (this .clusterConfigs );
353
463
@@ -373,6 +483,9 @@ public MultiClusterClientConfig build() {
373
483
374
484
config .fallbackExceptionList = this .fallbackExceptionList ;
375
485
486
+ config .retryOnFailover = this .retryOnFailover ;
487
+ config .failback = this .failback ;
488
+
376
489
return config ;
377
490
}
378
491
}
0 commit comments