2121import com .mongodb .connection .ClusterId ;
2222import com .mongodb .connection .ClusterSettings ;
2323import com .mongodb .connection .ClusterType ;
24+ import com .mongodb .connection .ServerDescription ;
2425import com .mongodb .lang .Nullable ;
2526
2627import java .util .ArrayList ;
2728import java .util .Collection ;
2829import java .util .Collections ;
2930import java .util .List ;
3031import java .util .concurrent .ThreadLocalRandom ;
32+ import java .util .stream .Collectors ;
3133
3234import static com .mongodb .assertions .Assertions .assertNotNull ;
3335
@@ -38,7 +40,6 @@ public final class DnsMultiServerCluster extends AbstractMultiServerCluster {
3840 private final DnsSrvRecordMonitor dnsSrvRecordMonitor ;
3941 private volatile MongoException srvResolutionException ;
4042
41-
4243 public DnsMultiServerCluster (final ClusterId clusterId , final ClusterSettings settings , final ClusterableServerFactory serverFactory ,
4344 final DnsSrvRecordMonitorFactory dnsSrvRecordMonitorFactory ) {
4445 super (clusterId , settings , serverFactory );
@@ -57,17 +58,33 @@ public void initialize(final Collection<ServerAddress> hosts) {
5758 }
5859 }
5960
60- private Collection <ServerAddress > applySrvMaxHosts (final Collection <ServerAddress > hosts ) {
61- Collection <ServerAddress > newHosts = hosts ;
61+ private Collection <ServerAddress > applySrvMaxHosts (final Collection <ServerAddress > latestSrvHosts ) {
6262 Integer srvMaxHosts = getSettings ().getSrvMaxHosts ();
63- if (srvMaxHosts != null && srvMaxHosts > 0 ) {
64- if (srvMaxHosts < hosts .size ()) {
65- List <ServerAddress > newHostsList = new ArrayList <>(hosts );
66- Collections .shuffle (newHostsList , ThreadLocalRandom .current ());
67- newHosts = newHostsList .subList (0 , srvMaxHosts );
68- }
63+ if (srvMaxHosts == null || srvMaxHosts <= 0 || latestSrvHosts .size () <= srvMaxHosts ) {
64+ return new ArrayList <>(latestSrvHosts );
6965 }
70- return newHosts ;
66+ List <ServerAddress > activeHosts = getActivePriorHosts (latestSrvHosts );
67+ int numNewHostsToAdd = srvMaxHosts - activeHosts .size ();
68+ activeHosts .addAll (addShuffledHosts (latestSrvHosts , activeHosts , numNewHostsToAdd ));
69+
70+ return activeHosts ;
71+ }
72+
73+ private List <ServerAddress > getActivePriorHosts (final Collection <ServerAddress > latestSrvHosts ) {
74+ List <ServerAddress > priorHosts = DnsMultiServerCluster .this .getCurrentDescription ().getServerDescriptions ().stream ()
75+ .map (ServerDescription ::getAddress ).collect (Collectors .toList ());
76+ priorHosts .removeIf (host -> !latestSrvHosts .contains (host ));
77+
78+ return priorHosts ;
79+ }
80+
81+ private List <ServerAddress > addShuffledHosts (final Collection <ServerAddress > latestSrvHosts ,
82+ final List <ServerAddress > activePriorHosts , final int numNewHostsToAdd ) {
83+ List <ServerAddress > addedHosts = new ArrayList <>(latestSrvHosts );
84+ addedHosts .removeAll (activePriorHosts );
85+ Collections .shuffle (addedHosts , ThreadLocalRandom .current ());
86+
87+ return addedHosts .subList (0 , numNewHostsToAdd );
7188 }
7289
7390 @ Override
0 commit comments