2020import java .io .InterruptedIOException ;
2121import java .net .SocketTimeoutException ;
2222import java .util .ArrayList ;
23- import java .util .Arrays ;
2423import java .util .List ;
2524import java .util .concurrent .Executors ;
2625import java .util .concurrent .ScheduledExecutorService ;
3130import static com .mongodb .ClusterConnectionMode .Single ;
3231import static com .mongodb .ClusterType .ReplicaSet ;
3332import static com .mongodb .ClusterType .Sharded ;
33+ import static com .mongodb .ClusterType .Unknown ;
3434import static com .mongodb .MongoAuthority .Type .Set ;
3535import static java .util .concurrent .TimeUnit .MILLISECONDS ;
3636import static org .bson .util .Assertions .isTrue ;
@@ -52,14 +52,19 @@ public class DBTCPConnector implements DBConnector {
5252
5353 private final MyPort _myPort = new MyPort ();
5454
55- private ServerSelector prefixedServerSelector ;
55+ private final ClusterConnectionMode connectionMode ;
56+
57+ private ClusterType type = ClusterType .Unknown ;
58+ private MongosHAServerSelector mongosHAServerSelector ;
5659
5760 /**
5861 * @param mongo the Mongo instance
5962 * @throws MongoException
6063 */
6164 public DBTCPConnector ( Mongo mongo ) {
6265 _mongo = mongo ;
66+ connectionMode = _mongo .getAuthority ().getType () == Set || _mongo .getMongoOptions ().getRequiredReplicaSetName () != null ?
67+ Multiple : Single ;
6368 }
6469
6570 public void start () {
@@ -76,8 +81,7 @@ public void start() {
7681 Clusters .create (clusterId ,
7782 ClusterSettings .builder ()
7883 .hosts (_mongo .getAuthority ().getServerAddresses ())
79- .mode (_mongo .getAuthority ().getType () == Set || options .getRequiredReplicaSetName () != null ?
80- Multiple : Single )
84+ .mode (connectionMode )
8185 .requiredReplicaSetName (_mongo .getMongoOptions ().getRequiredReplicaSetName ())
8286 .build (),
8387 ServerSettings .builder ()
@@ -326,7 +330,7 @@ private Response innerCall(final DB db, final DBCollection coll, final OutMessag
326330 public ServerAddress getAddress () {
327331 isTrue ("open" , !_closed );
328332 ClusterDescription clusterDescription = getClusterDescription ();
329- if (clusterDescription . getConnectionMode () == Single ) {
333+ if (connectionMode == Single ) {
330334 return clusterDescription .getAny ().get (0 ).getAddress ();
331335 }
332336 if (clusterDescription .getPrimaries ().isEmpty ()) {
@@ -362,16 +366,13 @@ public List<ServerAddress> getServerAddressList() {
362366
363367 public ReplicaSetStatus getReplicaSetStatus () {
364368 isTrue ("open" , !_closed );
365- ClusterDescription description = getClusterDescription ();
366- return description .getType () == ReplicaSet &&
367- description .getConnectionMode () == Multiple
368- ? new ReplicaSetStatus (description ) : null ;
369+ return getType () == ReplicaSet && connectionMode == Multiple ? new ReplicaSetStatus (getClusterDescription ()) : null ;
369370 }
370371
371372 // This call can block if it's not yet known.
372373 boolean isMongosConnection () {
373374 isTrue ("open" , !_closed );
374- return getClusterDescription (). getType () == Sharded ;
375+ return getType () == Sharded ;
375376 }
376377
377378 public String getConnectPoint (){
@@ -393,8 +394,7 @@ private boolean shouldRetryQuery(ReadPreference readPreference, final DBCollecti
393394 if (readPreference .equals (ReadPreference .primary ())) {
394395 return false ;
395396 }
396- ClusterDescription description = getClusterDescription ();
397- return description .getConnectionMode () == Multiple && description .getType () == ReplicaSet ;
397+ return connectionMode == Multiple && getType () == ReplicaSet ;
398398 }
399399
400400 private ClusterDescription getClusterDescription () {
@@ -501,7 +501,7 @@ void requestEnsureConnection(){
501501 if ( getPinnedRequestPortForThread () != null )
502502 return ;
503503
504- setPinnedRequestPortForThread (getConnection (new ReadPreferenceServerSelector (ReadPreference .primary ())));
504+ setPinnedRequestPortForThread (getConnection (createServerSelector (ReadPreference .primary ())));
505505 }
506506
507507 private DBPort getConnection (final ServerSelector serverSelector ) {
@@ -551,23 +551,37 @@ void setPinnedRequestPortForThread(final DBPort port) {
551551 private final ThreadLocal <PinnedRequestStatus > pinnedRequestStatusThreadLocal = new ThreadLocal <PinnedRequestStatus >();
552552 }
553553
554- private ServerSelector createServerSelector (final ReadPreference readPref ) {
555- return new CompositeServerSelector (Arrays .asList (getPrefixedServerSelector (),
556- new ReadPreferenceServerSelector (readPref ),
557- new LatencyMinimizingServerSelector (_mongo .getMongoOptions ()
558- .acceptableLatencyDifferenceMS , MILLISECONDS )));
559- }
560-
561- private synchronized ServerSelector getPrefixedServerSelector () {
562- if (prefixedServerSelector == null ) {
563- ClusterDescription clusterDescription = getClusterDescription ();
564- if (clusterDescription .getConnectionMode () == Multiple && clusterDescription .getType () == Sharded ) {
565- prefixedServerSelector = new MongosHAServerSelector ();
554+ private ServerSelector createServerSelector (final ReadPreference readPreference ) {
555+ if (connectionMode == Multiple ) {
556+ List <ServerSelector > serverSelectorList = new ArrayList <ServerSelector >();
557+ if (getType () == Sharded ) {
558+ serverSelectorList .add (getMongosHAServerSelector ());
559+ } else if (getType () == ReplicaSet ) {
560+ serverSelectorList .add (new ReadPreferenceServerSelector (readPreference ));
566561 } else {
567- prefixedServerSelector = new NoOpServerSelector ( );
562+ serverSelectorList . add ( new AnyServerSelector () );
568563 }
564+ serverSelectorList .add (new LatencyMinimizingServerSelector (_mongo .getMongoOptions ().acceptableLatencyDifferenceMS ,
565+ MILLISECONDS ));
566+ return new CompositeServerSelector (serverSelectorList );
567+ } else {
568+ return new AnyServerSelector ();
569+ }
570+ }
571+
572+ private synchronized ClusterType getType () {
573+ if (type == Unknown ) {
574+ type = getClusterDescription ().getType ();
575+ }
576+ return type ;
577+ }
578+
579+ // There needs to be just one instance of this because it's stateful between requests
580+ private synchronized MongosHAServerSelector getMongosHAServerSelector () {
581+ if (mongosHAServerSelector == null ) {
582+ mongosHAServerSelector = new MongosHAServerSelector ();
569583 }
570- return prefixedServerSelector ;
584+ return mongosHAServerSelector ;
571585 }
572586
573587 static class PinnedRequestStatus {
0 commit comments