50
50
import java .util .ArrayList ;
51
51
import java .util .Collection ;
52
52
import java .util .Collections ;
53
- import java .util .HashSet ;
54
53
import java .util .Iterator ;
55
54
import java .util .List ;
56
- import java .util .Set ;
57
55
import java .util .concurrent .ArrayBlockingQueue ;
58
56
import java .util .concurrent .BlockingQueue ;
59
57
import java .util .concurrent .ExecutorService ;
60
58
import java .util .concurrent .RejectedExecutionException ;
61
59
import java .util .concurrent .Semaphore ;
62
60
import java .util .concurrent .atomic .AtomicBoolean ;
61
+ import java .util .concurrent .atomic .AtomicLong ;
63
62
import java .util .function .Function ;
64
63
import java .util .function .Predicate ;
65
64
import java .util .function .Supplier ;
@@ -84,7 +83,6 @@ final class RemoteClusterConnection implements TransportConnectionListener, Clos
84
83
85
84
private final TransportService transportService ;
86
85
private final ConnectionManager connectionManager ;
87
- private final ConnectedNodes connectedNodes ;
88
86
private final String clusterAlias ;
89
87
private final int maxNumRemoteConnections ;
90
88
private final Predicate <DiscoveryNode > nodePredicate ;
@@ -123,7 +121,6 @@ final class RemoteClusterConnection implements TransportConnectionListener, Clos
123
121
this .nodePredicate = nodePredicate ;
124
122
this .clusterAlias = clusterAlias ;
125
123
this .connectionManager = connectionManager ;
126
- this .connectedNodes = new ConnectedNodes (clusterAlias );
127
124
this .seedNodes = Collections .unmodifiableList (seedNodes );
128
125
this .skipUnavailable = RemoteClusterService .REMOTE_CLUSTER_SKIP_UNAVAILABLE
129
126
.getConcreteSettingForNamespace (clusterAlias ).get (settings );
@@ -176,8 +173,7 @@ boolean isSkipUnavailable() {
176
173
177
174
@ Override
178
175
public void onNodeDisconnected (DiscoveryNode node ) {
179
- boolean remove = connectedNodes .remove (node );
180
- if (remove && connectedNodes .size () < maxNumRemoteConnections ) {
176
+ if (connectionManager .size () < maxNumRemoteConnections ) {
181
177
// try to reconnect and fill up the slot of the disconnected node
182
178
connectHandler .forceConnect ();
183
179
}
@@ -188,7 +184,7 @@ public void onNodeDisconnected(DiscoveryNode node) {
188
184
* will invoke the listener immediately.
189
185
*/
190
186
void ensureConnected (ActionListener <Void > voidActionListener ) {
191
- if (connectedNodes .size () == 0 ) {
187
+ if (connectionManager .size () == 0 ) {
192
188
connectHandler .connect (voidActionListener );
193
189
} else {
194
190
voidActionListener .onResponse (null );
@@ -466,14 +462,13 @@ private void collectRemoteNodes(Iterator<Supplier<DiscoveryNode>> seedNodes, fin
466
462
}
467
463
468
464
final DiscoveryNode handshakeNode = maybeAddProxyAddress (proxyAddress , handshakeResponse .getDiscoveryNode ());
469
- if (nodePredicate .test (handshakeNode ) && connectedNodes .size () < maxNumRemoteConnections ) {
465
+ if (nodePredicate .test (handshakeNode ) && manager .size () < maxNumRemoteConnections ) {
470
466
PlainActionFuture .get (fut -> manager .connectToNode (handshakeNode , null ,
471
467
transportService .connectionValidator (handshakeNode ), ActionListener .map (fut , x -> null )));
472
468
if (remoteClusterName .get () == null ) {
473
469
assert handshakeResponse .getClusterName ().value () != null ;
474
470
remoteClusterName .set (handshakeResponse .getClusterName ());
475
471
}
476
- connectedNodes .add (handshakeNode );
477
472
}
478
473
ClusterStateRequest request = new ClusterStateRequest ();
479
474
request .clear ();
@@ -580,12 +575,11 @@ public void handleResponse(ClusterStateResponse response) {
580
575
Iterable <DiscoveryNode > nodesIter = nodes .getNodes ()::valuesIt ;
581
576
for (DiscoveryNode n : nodesIter ) {
582
577
DiscoveryNode node = maybeAddProxyAddress (proxyAddress , n );
583
- if (nodePredicate .test (node ) && connectedNodes .size () < maxNumRemoteConnections ) {
578
+ if (nodePredicate .test (node ) && connectionManager .size () < maxNumRemoteConnections ) {
584
579
try {
585
580
// noop if node is connected
586
581
PlainActionFuture .get (fut -> connectionManager .connectToNode (node , null ,
587
582
transportService .connectionValidator (node ), ActionListener .map (fut , x -> null )));
588
- connectedNodes .add (node );
589
583
} catch (ConnectTransportException | IllegalStateException ex ) {
590
584
// ISE if we fail the handshake with an version incompatible node
591
585
// fair enough we can't connect just move on
@@ -628,15 +622,20 @@ boolean assertNoRunningConnections() { // for testing only
628
622
}
629
623
630
624
boolean isNodeConnected (final DiscoveryNode node ) {
631
- return connectedNodes . contains (node );
625
+ return connectionManager . nodeConnected (node );
632
626
}
633
627
634
- DiscoveryNode getAnyConnectedNode () {
635
- return connectedNodes .getAny ();
636
- }
628
+ private final AtomicLong nextNodeId = new AtomicLong ();
637
629
638
- void addConnectedNode (DiscoveryNode node ) {
639
- connectedNodes .add (node );
630
+ DiscoveryNode getAnyConnectedNode () {
631
+ List <DiscoveryNode > nodes = new ArrayList <>(connectionManager .connectedNodes ());
632
+ if (nodes .isEmpty ()) {
633
+ throw new NoSuchRemoteClusterException (clusterAlias );
634
+ } else {
635
+ long curr ;
636
+ while ((curr = nextNodeId .incrementAndGet ()) == Long .MIN_VALUE );
637
+ return nodes .get (Math .floorMod (curr , nodes .size ()));
638
+ }
640
639
}
641
640
642
641
/**
@@ -647,67 +646,13 @@ public RemoteConnectionInfo getConnectionInfo() {
647
646
clusterAlias ,
648
647
seedNodes .stream ().map (Tuple ::v1 ).collect (Collectors .toList ()),
649
648
maxNumRemoteConnections ,
650
- connectedNodes . size (),
649
+ getNumNodesConnected (),
651
650
initialConnectionTimeout ,
652
651
skipUnavailable );
653
652
}
654
653
655
654
int getNumNodesConnected () {
656
- return connectedNodes .size ();
657
- }
658
-
659
- private static final class ConnectedNodes {
660
-
661
- private final Set <DiscoveryNode > nodeSet = new HashSet <>();
662
- private final String clusterAlias ;
663
-
664
- private Iterator <DiscoveryNode > currentIterator = null ;
665
-
666
- private ConnectedNodes (String clusterAlias ) {
667
- this .clusterAlias = clusterAlias ;
668
- }
669
-
670
- public synchronized DiscoveryNode getAny () {
671
- ensureIteratorAvailable ();
672
- if (currentIterator .hasNext ()) {
673
- return currentIterator .next ();
674
- } else {
675
- throw new NoSuchRemoteClusterException (clusterAlias );
676
- }
677
- }
678
-
679
- synchronized boolean remove (DiscoveryNode node ) {
680
- final boolean setRemoval = nodeSet .remove (node );
681
- if (setRemoval ) {
682
- currentIterator = null ;
683
- }
684
- return setRemoval ;
685
- }
686
-
687
- synchronized boolean add (DiscoveryNode node ) {
688
- final boolean added = nodeSet .add (node );
689
- if (added ) {
690
- currentIterator = null ;
691
- }
692
- return added ;
693
- }
694
-
695
- synchronized int size () {
696
- return nodeSet .size ();
697
- }
698
-
699
- synchronized boolean contains (DiscoveryNode node ) {
700
- return nodeSet .contains (node );
701
- }
702
-
703
- private synchronized void ensureIteratorAvailable () {
704
- if (currentIterator == null ) {
705
- currentIterator = nodeSet .iterator ();
706
- } else if (currentIterator .hasNext () == false && nodeSet .isEmpty () == false ) {
707
- // iterator rollover
708
- currentIterator = nodeSet .iterator ();
709
- }
710
- }
655
+ return connectionManager .size ();
711
656
}
712
657
713
658
private static ConnectionManager createConnectionManager (ConnectionProfile connectionProfile , TransportService transportService ) {
0 commit comments