@@ -70,6 +70,8 @@ public class EVCacheClientPool implements Runnable, EVCacheClientPoolMBean {
70
70
71
71
// name of the duet EVCache application, if applicable.
72
72
private final Property <String > duet ;
73
+ // indicates if duet needs to be primary
74
+ private final Property <Boolean > duetPrimary ;
73
75
// evCacheClientPool of the duet EVCache application, if applicable. Supports daisy chaining.
74
76
private EVCacheClientPool duetClientPool ;
75
77
@@ -174,6 +176,8 @@ public Property<Boolean> get(Object _serverGroup) {
174
176
setupDuet ();
175
177
});
176
178
179
+ this .duetPrimary = config .getPropertyRepository ().get (appName + ".duet.primary" , Boolean .class ).orElseGet ("evcache.duet.primary" ).orElse (false );
180
+
177
181
tagList = new ArrayList <Tag >(2 );
178
182
EVCacheMetricsFactory .getInstance ().addAppNameTags (tagList , _appName );
179
183
@@ -251,11 +255,20 @@ private EVCacheClient getEVCacheClientForReadInternal() {
251
255
public EVCacheClient getEVCacheClientForRead () {
252
256
EVCacheClient evCacheClient = getEVCacheClientForReadInternal ();
253
257
254
- if (evCacheClient != null ) {
258
+ // most common production scenario
259
+ if (null == duetClientPool ) {
255
260
return evCacheClient ;
256
261
}
257
262
258
- return duetClientPool != null ? duetClientPool .getEVCacheClientForRead () : null ;
263
+ // return duet if current client is not available or if duet is primary
264
+ if (null == evCacheClient || duetPrimary .get ()) {
265
+ EVCacheClient duetClient = duetClientPool .getEVCacheClientForRead ();
266
+
267
+ // if duetClient is not present, fallback to evCacheClient
268
+ return null == duetClient ? evCacheClient : duetClient ;
269
+ }
270
+
271
+ return evCacheClient ;
259
272
}
260
273
261
274
private List <EVCacheClient > getAllEVCacheClientForReadInternal () {
@@ -288,17 +301,26 @@ private List<EVCacheClient> getAllEVCacheClientForReadInternal() {
288
301
289
302
public List <EVCacheClient > getAllEVCacheClientForRead () {
290
303
List <EVCacheClient > evCacheClients = getAllEVCacheClientForReadInternal ();
291
- if (duetClientPool != null ) {
292
- List <EVCacheClient > duetEVCacheClients = duetClientPool .getAllEVCacheClientForRead ();
293
- if (null == evCacheClients )
294
- return duetEVCacheClients ;
295
304
296
- if (null == duetEVCacheClients )
297
- return evCacheClients ;
305
+ // most common production scenario
306
+ if (null == duetClientPool ) {
307
+ return evCacheClients ;
308
+ }
298
309
299
- evCacheClients .addAll (duetClientPool .getAllEVCacheClientForRead ());
310
+ List <EVCacheClient > duetEVCacheClients = duetClientPool .getAllEVCacheClientForRead ();
311
+ if (null == evCacheClients )
312
+ return duetEVCacheClients ;
313
+
314
+ if (null == duetEVCacheClients )
315
+ return evCacheClients ;
316
+
317
+ if (duetPrimary .get ()) {
318
+ duetEVCacheClients .addAll (evCacheClients );
319
+ return duetEVCacheClients ;
320
+ } else {
321
+ evCacheClients .addAll (duetEVCacheClients );
322
+ return evCacheClients ;
300
323
}
301
- return evCacheClients ;
302
324
}
303
325
304
326
private EVCacheClient selectClient (List <EVCacheClient > clients ) {
@@ -340,11 +362,20 @@ private EVCacheClient getEVCacheClientForReadExcludeInternal(ServerGroup rsetUse
340
362
public EVCacheClient getEVCacheClientForReadExclude (ServerGroup rsetUsed ) {
341
363
EVCacheClient evCacheClient = getEVCacheClientForReadExcludeInternal (rsetUsed );
342
364
343
- if (evCacheClient != null ) {
365
+ // most common production scenario
366
+ if (null == duetClientPool ) {
344
367
return evCacheClient ;
345
368
}
346
369
347
- return duetClientPool != null ? duetClientPool .getEVCacheClientForReadExclude (rsetUsed ) : null ;
370
+ // return duet if current client is not available or if duet is primary
371
+ if (null == evCacheClient || duetPrimary .get ()) {
372
+ EVCacheClient duetClient = duetClientPool .getEVCacheClientForReadExclude (rsetUsed );
373
+
374
+ // if duetClient is not present, fallback to evCacheClient
375
+ return null == duetClient ? evCacheClient : duetClient ;
376
+ }
377
+
378
+ return evCacheClient ;
348
379
}
349
380
350
381
private EVCacheClient getEVCacheClientInternal (ServerGroup serverGroup ) {
@@ -374,11 +405,20 @@ private EVCacheClient getEVCacheClientInternal(ServerGroup serverGroup) {
374
405
public EVCacheClient getEVCacheClient (ServerGroup serverGroup ) {
375
406
EVCacheClient evCacheClient = getEVCacheClientInternal (serverGroup );
376
407
377
- if (evCacheClient != null ) {
408
+ // most common production scenario
409
+ if (null == duetClientPool ) {
378
410
return evCacheClient ;
379
411
}
380
412
381
- return duetClientPool != null ? duetClientPool .getEVCacheClient (serverGroup ) : null ;
413
+ // return duet if current client is not available or if duet is primary
414
+ if (null == evCacheClient || duetPrimary .get ()) {
415
+ EVCacheClient duetClient = duetClientPool .getEVCacheClient (serverGroup );
416
+
417
+ // if duetClient is not present, fallback to evCacheClient
418
+ return null == duetClient ? evCacheClient : duetClient ;
419
+ }
420
+
421
+ return evCacheClient ;
382
422
}
383
423
384
424
private List <EVCacheClient > getEVCacheClientsForReadExcludingInternal (ServerGroup serverGroupToExclude ) {
@@ -431,17 +471,26 @@ private List<EVCacheClient> getEVCacheClientsForReadExcludingInternal(ServerGrou
431
471
432
472
public List <EVCacheClient > getEVCacheClientsForReadExcluding (ServerGroup serverGroupToExclude ) {
433
473
List <EVCacheClient > evCacheClients = getEVCacheClientsForReadExcludingInternal (serverGroupToExclude );
434
- if (duetClientPool != null ) {
435
- List <EVCacheClient > duetEVCacheClients = duetClientPool .getEVCacheClientsForReadExcluding (serverGroupToExclude );
436
- if (null == evCacheClients )
437
- return duetEVCacheClients ;
438
474
439
- if (null == duetEVCacheClients )
440
- return evCacheClients ;
475
+ // most common production scenario
476
+ if (null == duetClientPool ) {
477
+ return evCacheClients ;
478
+ }
479
+
480
+ List <EVCacheClient > duetEVCacheClients = duetClientPool .getEVCacheClientsForReadExcluding (serverGroupToExclude );
481
+ if (null == evCacheClients )
482
+ return duetEVCacheClients ;
483
+
484
+ if (null == duetEVCacheClients )
485
+ return evCacheClients ;
441
486
487
+ if (duetPrimary .get ()) {
488
+ duetEVCacheClients .addAll (evCacheClients );
489
+ return duetEVCacheClients ;
490
+ } else {
442
491
evCacheClients .addAll (duetEVCacheClients );
492
+ return evCacheClients ;
443
493
}
444
- return evCacheClients ;
445
494
}
446
495
447
496
public boolean isInWriteOnly (ServerGroup serverGroup ) {
@@ -503,27 +552,39 @@ private EVCacheClient[] getWriteOnlyEVCacheClientsInternal() {
503
552
}
504
553
505
554
public EVCacheClient [] getWriteOnlyEVCacheClients () {
506
- EVCacheClient [] evCacheClients = null ;
507
- try {
508
- evCacheClients = getWriteOnlyEVCacheClientsInternal ();
509
- if (duetClientPool != null ) {
510
- EVCacheClient [] duetEVCacheClients = duetClientPool .getWriteOnlyEVCacheClients ();
511
-
512
- // common scenario for duet usage
513
- if (null == evCacheClients || evCacheClients .length == 0 ) {
514
- return duetEVCacheClients ;
515
- }
516
-
517
- if (null != duetEVCacheClients && duetEVCacheClients .length > 0 ) {
518
- EVCacheClient [] allEVCacheClients = Arrays .copyOf (evCacheClients , evCacheClients .length + duetEVCacheClients .length );
519
- System .arraycopy (duetEVCacheClients , 0 , allEVCacheClients , evCacheClients .length , duetEVCacheClients .length );
520
- return allEVCacheClients ;
521
- }
522
- }
523
- return evCacheClients ;
524
- } finally {
525
- if (evCacheClients == null ) return new EVCacheClient [0 ];
526
- }
555
+ EVCacheClient [] evCacheClients = getWriteOnlyEVCacheClientsInternal ();
556
+
557
+ // most common production scenario
558
+ if (null == duetClientPool ) {
559
+ return evCacheClients ;
560
+ }
561
+
562
+ EVCacheClient [] duetEVCacheClients = duetClientPool .getWriteOnlyEVCacheClients ();
563
+ if (null == evCacheClients || evCacheClients .length == 0 ) {
564
+ return duetEVCacheClients ;
565
+ }
566
+
567
+ if (null == duetEVCacheClients || duetEVCacheClients .length == 0 ) {
568
+ return evCacheClients ;
569
+ }
570
+
571
+ if (duetPrimary .get ()) {
572
+ // return write-only of duet app and all writers of original app to which duet is attached
573
+ // get all writers of original app
574
+ evCacheClients = getEVCacheClientForWriteInternal ();
575
+
576
+ EVCacheClient [] allEVCacheClients = Arrays .copyOf (duetEVCacheClients , duetEVCacheClients .length + evCacheClients .length );
577
+ System .arraycopy (evCacheClients , 0 , allEVCacheClients , duetEVCacheClients .length , evCacheClients .length );
578
+ return allEVCacheClients ;
579
+ } else {
580
+ // return write-only of original app and all writers of duet app
581
+ // get all writers of duet app
582
+ duetEVCacheClients = duetClientPool .getEVCacheClientForWrite ();
583
+
584
+ EVCacheClient [] allEVCacheClients = Arrays .copyOf (evCacheClients , evCacheClients .length + duetEVCacheClients .length );
585
+ System .arraycopy (duetEVCacheClients , 0 , allEVCacheClients , evCacheClients .length , duetEVCacheClients .length );
586
+ return allEVCacheClients ;
587
+ }
527
588
}
528
589
529
590
EVCacheClient [] getAllWriteClients () {
@@ -594,27 +655,31 @@ private EVCacheClient[] getEVCacheClientForWriteInternal() {
594
655
}
595
656
596
657
public EVCacheClient [] getEVCacheClientForWrite () {
597
- EVCacheClient [] evCacheClients = null ;
598
- try {
599
- evCacheClients = getEVCacheClientForWriteInternal ();
600
- if (duetClientPool != null ) {
601
- EVCacheClient [] duetEVCacheClients = duetClientPool .getEVCacheClientForWrite ();
602
-
603
- // common scenario for duet usage
604
- if (null == evCacheClients || evCacheClients .length == 0 ) {
605
- return duetEVCacheClients ;
606
- }
607
-
608
- if (null != duetEVCacheClients && duetEVCacheClients .length > 0 ) {
609
- EVCacheClient [] allEVCacheClients = Arrays .copyOf (evCacheClients , evCacheClients .length + duetEVCacheClients .length );
610
- System .arraycopy (duetEVCacheClients , 0 , allEVCacheClients , evCacheClients .length , duetEVCacheClients .length );
611
- return allEVCacheClients ;
612
- }
613
- }
614
- return evCacheClients ;
615
- } finally {
616
- if (evCacheClients == null ) return new EVCacheClient [0 ];
617
- }
658
+ EVCacheClient [] evCacheClients = getEVCacheClientForWriteInternal ();
659
+
660
+ // most common production scenario
661
+ if (null == duetClientPool ) {
662
+ return evCacheClients ;
663
+ }
664
+
665
+ EVCacheClient [] duetEVCacheClients = duetClientPool .getEVCacheClientForWrite ();
666
+ if (null == evCacheClients || evCacheClients .length == 0 ) {
667
+ return duetEVCacheClients ;
668
+ }
669
+
670
+ if (null == duetEVCacheClients || duetEVCacheClients .length == 0 ) {
671
+ return evCacheClients ;
672
+ }
673
+
674
+ if (duetPrimary .get ()) {
675
+ EVCacheClient [] allEVCacheClients = Arrays .copyOf (duetEVCacheClients , duetEVCacheClients .length + evCacheClients .length );
676
+ System .arraycopy (evCacheClients , 0 , allEVCacheClients , duetEVCacheClients .length , evCacheClients .length );
677
+ return allEVCacheClients ;
678
+ } else {
679
+ EVCacheClient [] allEVCacheClients = Arrays .copyOf (evCacheClients , evCacheClients .length + duetEVCacheClients .length );
680
+ System .arraycopy (duetEVCacheClients , 0 , allEVCacheClients , evCacheClients .length , duetEVCacheClients .length );
681
+ return allEVCacheClients ;
682
+ }
618
683
}
619
684
620
685
private void refresh () throws IOException {
@@ -1432,7 +1497,7 @@ public String getFallbackServerGroup() {
1432
1497
}
1433
1498
1434
1499
public boolean supportsFallback () {
1435
- return memcachedFallbackReadInstances .getSize () > 1 || (duetClientPool != null && duetClientPool .supportsFallback ());
1500
+ return memcachedFallbackReadInstances .getSize () > 1 || (duetClientPool != null && duetPrimary . get () && duetClientPool .supportsFallback ());
1436
1501
}
1437
1502
1438
1503
public boolean isLogEventEnabled () {
@@ -1486,6 +1551,9 @@ public Property<Integer> getOpQueueMaxBlockTime() {
1486
1551
}
1487
1552
1488
1553
public Property <Integer > getOperationTimeout () {
1554
+ if (duetClientPool !=null && duetPrimary .get ()) {
1555
+ return duetClientPool .getOperationTimeout ();
1556
+ }
1489
1557
return _operationTimeout ;
1490
1558
}
1491
1559
@@ -1528,6 +1596,9 @@ public Map<ServerGroup, Property<Boolean>> getWriteOnlyFastPropertyMap() {
1528
1596
}
1529
1597
1530
1598
public Property <Integer > getReadTimeout () {
1599
+ if (duetClientPool != null && duetPrimary .get ()) {
1600
+ return duetClientPool .getReadTimeout ();
1601
+ }
1531
1602
return _readTimeout ;
1532
1603
}
1533
1604
0 commit comments