1616
1717package com .mongodb ;
1818
19+ import org .bson .types .ObjectId ;
20+
1921import java .net .UnknownHostException ;
2022import java .util .ArrayList ;
2123import java .util .HashSet ;
@@ -42,6 +44,7 @@ final class MultiServerCluster extends BaseCluster {
4244
4345 private ClusterType clusterType ;
4446 private String replicaSetName ;
47+ private ObjectId maxElectionId ;
4548 private final ConcurrentMap <ServerAddress , ServerTuple > addressToServerTupleMap =
4649 new ConcurrentHashMap <ServerAddress , ServerTuple >();
4750
@@ -117,6 +120,7 @@ private void onChange(final ChangeEvent<ServerDescription> event) {
117120 return ;
118121 }
119122
123+ boolean shouldUpdateDescription = true ;
120124 synchronized (this ) {
121125 ServerDescription newDescription = event .getNewValue ();
122126 ServerTuple serverTuple = addressToServerTupleMap .get (newDescription .getAddress ());
@@ -132,36 +136,40 @@ private void onChange(final ChangeEvent<ServerDescription> event) {
132136
133137 switch (clusterType ) {
134138 case ReplicaSet :
135- handleReplicaSetMemberChanged (newDescription );
139+ shouldUpdateDescription = handleReplicaSetMemberChanged (newDescription );
136140 break ;
137141 case Sharded :
138- handleShardRouterChanged (newDescription );
142+ shouldUpdateDescription = handleShardRouterChanged (newDescription );
139143 break ;
140144 case StandAlone :
141- handleStandAloneChanged (newDescription );
145+ shouldUpdateDescription = handleStandAloneChanged (newDescription );
142146 break ;
143147 default :
144148 break ;
145149 }
146150 }
147151
148- serverTuple .description = newDescription ;
149- updateDescription ();
152+ if (shouldUpdateDescription ) {
153+ serverTuple .description = newDescription ;
154+ updateDescription ();
155+ }
156+ }
157+ if (shouldUpdateDescription ) {
158+ fireChangeEvent ();
150159 }
151- fireChangeEvent ();
152160 }
153161
154- private void handleReplicaSetMemberChanged (final ServerDescription newDescription ) {
162+ private boolean handleReplicaSetMemberChanged (final ServerDescription newDescription ) {
155163 if (!newDescription .isReplicaSetMember ()) {
156164 LOGGER .severe (format ("Expecting replica set member, but found a %s. Removing %s from client view of cluster." ,
157165 newDescription .getType (), newDescription .getAddress ()));
158166 removeServer (newDescription .getAddress ());
159- return ;
167+ return true ;
160168 }
161169
162170 if (newDescription .getType () == ReplicaSetGhost ) {
163171 LOGGER .info (format ("Server %s does not appear to be a member of an initiated replica set." , newDescription .getAddress ()));
164- return ;
172+ return true ;
165173 }
166174
167175 if (replicaSetName == null ) {
@@ -174,39 +182,51 @@ private void handleReplicaSetMemberChanged(final ServerDescription newDescriptio
174182 replicaSetName , newDescription .getSetName (), newDescription .getAddress ()
175183 ));
176184 removeServer (newDescription .getAddress ());
177- return ;
185+ return true ;
178186 }
179187
180188 ensureServers (newDescription );
181189
182190 if (newDescription .isPrimary ()) {
191+ if (newDescription .getElectionId () != null ) {
192+ if (maxElectionId != null && maxElectionId .compareTo (newDescription .getElectionId ()) > 0 ) {
193+ addressToServerTupleMap .get (newDescription .getAddress ()).server .invalidate ();
194+ return false ;
195+ }
196+
197+ maxElectionId = newDescription .getElectionId ();
198+ }
199+
183200 if (isNotAlreadyPrimary (newDescription .getAddress ())) {
184201 LOGGER .info (format ("Discovered replica set primary %s" , newDescription .getAddress ()));
185202 }
186203 invalidateOldPrimaries (newDescription .getAddress ());
187204 }
205+ return true ;
188206 }
189207
190208 private boolean isNotAlreadyPrimary (final ServerAddress address ) {
191209 ServerTuple serverTuple = addressToServerTupleMap .get (address );
192210 return serverTuple == null || !serverTuple .description .isPrimary ();
193211 }
194212
195- private void handleShardRouterChanged (final ServerDescription newDescription ) {
213+ private boolean handleShardRouterChanged (final ServerDescription newDescription ) {
196214 if (newDescription .getClusterType () != Sharded ) {
197215 LOGGER .severe (format ("Expecting a %s, but found a %s. Removing %s from client view of cluster." ,
198216 ShardRouter , newDescription .getType (), newDescription .getAddress ()));
199217 removeServer (newDescription .getAddress ());
200218 }
219+ return true ;
201220 }
202221
203- private void handleStandAloneChanged (final ServerDescription newDescription ) {
222+ private boolean handleStandAloneChanged (final ServerDescription newDescription ) {
204223 if (getSettings ().getHosts ().size () > 1 ) {
205224 LOGGER .severe (format ("Expecting a single %s, but found more than one. Removing %s from client view of cluster." ,
206225 ServerType .StandAlone , newDescription .getAddress ()));
207226 clusterType = Unknown ;
208227 removeServer (newDescription .getAddress ());
209228 }
229+ return true ;
210230 }
211231
212232 private void addServer (final ServerAddress serverAddress ) {
0 commit comments