16
16
17
17
package com .mongodb .internal .connection ;
18
18
19
- import com .mongodb .MongoConfigurationException ;
19
+ import com .mongodb .MongoException ;
20
20
import com .mongodb .ServerAddress ;
21
21
import com .mongodb .connection .ClusterConnectionMode ;
22
22
import com .mongodb .connection .ClusterDescription ;
32
32
import org .bson .types .ObjectId ;
33
33
34
34
import java .util .ArrayList ;
35
+ import java .util .Collection ;
35
36
import java .util .Collections ;
36
37
import java .util .HashSet ;
37
38
import java .util .Iterator ;
47
48
import static com .mongodb .connection .ServerType .REPLICA_SET_GHOST ;
48
49
import static com .mongodb .connection .ServerType .SHARD_ROUTER ;
49
50
import static com .mongodb .connection .ServerType .STANDALONE ;
50
- import static com .mongodb .internal .connection .ServerAddressHelper .createServerAddress ;
51
- import static com .mongodb .internal .dns .DnsResolver .resolveHostFromSrvRecords ;
52
51
import static java .lang .String .format ;
53
52
54
- /**
55
- * This class needs to be final because we are leaking a reference to "this" from the constructor
56
- */
57
- public final class MultiServerCluster extends BaseCluster {
53
+ public abstract class AbstractMultiServerCluster extends BaseCluster {
58
54
private static final Logger LOGGER = Loggers .getLogger ("cluster" );
59
55
60
56
private ClusterType clusterType ;
@@ -64,7 +60,6 @@ public final class MultiServerCluster extends BaseCluster {
64
60
65
61
private final ConcurrentMap <ServerAddress , ServerTuple > addressToServerTupleMap =
66
62
new ConcurrentHashMap <ServerAddress , ServerTuple >();
67
- private volatile MongoConfigurationException srvResolutionException ;
68
63
69
64
private static final class ServerTuple {
70
65
private final ClusterableServer server ;
@@ -76,7 +71,7 @@ private ServerTuple(final ClusterableServer server, final ServerDescription desc
76
71
}
77
72
}
78
73
79
- public MultiServerCluster (final ClusterId clusterId , final ClusterSettings settings , final ClusterableServerFactory serverFactory ) {
74
+ AbstractMultiServerCluster (final ClusterId clusterId , final ClusterSettings settings , final ClusterableServerFactory serverFactory ) {
80
75
super (clusterId , settings , serverFactory );
81
76
isTrue ("connection mode is multiple" , settings .getMode () == ClusterConnectionMode .MULTIPLE );
82
77
clusterType = settings .getRequiredClusterType ();
@@ -85,33 +80,17 @@ public MultiServerCluster(final ClusterId clusterId, final ClusterSettings setti
85
80
if (LOGGER .isInfoEnabled ()) {
86
81
LOGGER .info (format ("Cluster created with settings %s" , settings .getShortDescription ()));
87
82
}
83
+ }
88
84
89
- if (settings .getSrvHost () != null ) {
90
- new Thread (new Runnable () {
91
- @ Override
92
- public void run () {
93
- List <ServerAddress > hosts = new ArrayList <ServerAddress >();
94
- try {
95
- List <String > resolvedHostNames = resolveHostFromSrvRecords (settings .getSrvHost ());
96
- for (String host : resolvedHostNames ) {
97
- hosts .add (createServerAddress (host ));
98
- }
99
- } catch (MongoConfigurationException e ) {
100
- srvResolutionException = e ;
101
- } catch (RuntimeException e ) {
102
- LOGGER .warn ("Unexpected runtime exception while resolving SRV record" , e );
103
- return ;
104
- }
105
- initialize (clusterId , settings , hosts , serverFactory );
106
- }
107
- }).start ();
108
- } else {
109
- initialize (clusterId , settings , settings .getHosts (), serverFactory );
110
- }
85
+ ClusterType getClusterType () {
86
+ return clusterType ;
87
+ }
88
+
89
+ MongoException getSrvResolutionException () {
90
+ return null ;
111
91
}
112
92
113
- private void initialize (final ClusterId clusterId , final ClusterSettings settings , final List <ServerAddress > serverAddresses ,
114
- final ClusterableServerFactory serverFactory ) {
93
+ protected void initialize (final Collection <ServerAddress > serverAddresses ) {
115
94
ClusterDescription newDescription ;
116
95
117
96
// synchronizing this code because addServer registers a callback which is re-entrant to this instance.
@@ -122,9 +101,12 @@ private void initialize(final ClusterId clusterId, final ClusterSettings setting
122
101
}
123
102
newDescription = updateDescription ();
124
103
}
125
- fireChangeEvent (new ClusterDescriptionChangedEvent (clusterId , newDescription ,
126
- new ClusterDescription (settings .getMode (), ClusterType .UNKNOWN , Collections .<ServerDescription >emptyList (),
127
- settings , serverFactory .getSettings ())));
104
+ fireChangeEvent (new ClusterDescriptionChangedEvent (getClusterId (), newDescription , createInitialDescription ()));
105
+ }
106
+
107
+ private ClusterDescription createInitialDescription () {
108
+ return new ClusterDescription (getSettings ().getMode (), ClusterType .UNKNOWN , Collections .<ServerDescription >emptyList (),
109
+ getSettings (), getServerFactory ().getSettings ());
128
110
}
129
111
130
112
@ Override
@@ -165,6 +147,34 @@ public void serverDescriptionChanged(final ServerDescriptionChangedEvent event)
165
147
}
166
148
}
167
149
150
+ void onChange (final Collection <ServerAddress > newHosts ) {
151
+ synchronized (this ) {
152
+ if (isClosed ()) {
153
+ return ;
154
+ }
155
+
156
+ for (ServerAddress cur : newHosts ) {
157
+ addServer (cur );
158
+ }
159
+
160
+ for (Iterator <ServerTuple > iterator = addressToServerTupleMap .values ().iterator (); iterator .hasNext ();) {
161
+ ServerTuple cur = iterator .next ();
162
+ if (!newHosts .contains (cur .description .getAddress ())) {
163
+ if (LOGGER .isInfoEnabled ()) {
164
+ LOGGER .info (format ("Removing %s from client view of cluster." , cur .description .getAddress ()));
165
+ }
166
+ iterator .remove ();
167
+ cur .server .close ();
168
+ }
169
+ }
170
+
171
+ ClusterDescription oldClusterDescription = getCurrentDescription ();
172
+ ClusterDescription newClusterDescription = updateDescription ();
173
+
174
+ fireChangeEvent (new ClusterDescriptionChangedEvent (getClusterId (), newClusterDescription , oldClusterDescription ));
175
+ }
176
+ }
177
+
168
178
private void onChange (final ServerDescriptionChangedEvent event ) {
169
179
ClusterDescription oldClusterDescription = null ;
170
180
ClusterDescription newClusterDescription = null ;
@@ -369,7 +379,7 @@ private ServerDescription getConnectingServerDescription(final ServerAddress ser
369
379
}
370
380
371
381
private ClusterDescription updateDescription () {
372
- ClusterDescription newDescription = new ClusterDescription (MULTIPLE , clusterType , srvResolutionException ,
382
+ ClusterDescription newDescription = new ClusterDescription (MULTIPLE , clusterType , getSrvResolutionException () ,
373
383
getNewServerDescriptionList (), getSettings (), getServerFactory ().getSettings ());
374
384
updateDescription (newDescription );
375
385
return newDescription ;
0 commit comments