@@ -586,6 +586,10 @@ pub struct ClientOptions {
586586 #[ builder( default ) ]
587587 pub write_concern : Option < WriteConcern > ,
588588
589+ /// Limit on the number of mongos connections that may be created for sharded topologies.
590+ #[ builder( default ) ]
591+ pub srv_max_hosts : Option < u32 > ,
592+
589593 /// Information from the SRV URI that generated these client options, if applicable.
590594 #[ builder( default , setter( skip) ) ]
591595 #[ serde( skip) ]
@@ -708,6 +712,8 @@ impl Serialize for ClientOptions {
708712 zlibcompressionlevel : & ' a Option < i32 > ,
709713
710714 loadbalanced : & ' a Option < bool > ,
715+
716+ srvmaxhosts : Option < i32 > ,
711717 }
712718
713719 let client_options = ClientOptionsHelper {
@@ -732,6 +738,7 @@ impl Serialize for ClientOptions {
732738 writeconcern : & self . write_concern ,
733739 loadbalanced : & self . load_balanced ,
734740 zlibcompressionlevel : & None ,
741+ srvmaxhosts : self . srv_max_hosts . map ( |v| v as i32 ) ,
735742 } ;
736743
737744 client_options. serialize ( serializer)
@@ -875,6 +882,9 @@ pub struct ConnectionString {
875882 /// [`Binary::to_uuid_with_representation`](bson::binary::Binary::to_uuid_with_representation).
876883 pub uuid_representation : Option < UuidRepresentation > ,
877884
885+ /// Limit on the number of mongos connections that may be created for sharded topologies.
886+ pub srv_max_hosts : Option < u32 > ,
887+
878888 wait_queue_timeout : Option < Duration > ,
879889 tls_insecure : Option < bool > ,
880890
@@ -1252,6 +1262,24 @@ impl ClientOptions {
12521262 options. load_balanced = config. load_balanced ;
12531263 }
12541264
1265+ if let Some ( max) = options. srv_max_hosts {
1266+ if max > 0 {
1267+ if options. repl_set_name . is_some ( ) {
1268+ return Err ( Error :: invalid_argument (
1269+ "srvMaxHosts and replicaSet cannot both be present" ,
1270+ ) ) ;
1271+ }
1272+ if options. load_balanced == Some ( true ) {
1273+ return Err ( Error :: invalid_argument (
1274+ "srvMaxHosts and loadBalanced=true cannot both be present" ,
1275+ ) ) ;
1276+ }
1277+ config. hosts = crate :: sdam:: choose_n ( & config. hosts , max as usize )
1278+ . cloned ( )
1279+ . collect ( ) ;
1280+ }
1281+ }
1282+
12551283 // Set the ClientOptions hosts to those found during the SRV lookup.
12561284 config. hosts
12571285 }
@@ -1338,6 +1366,7 @@ impl ClientOptions {
13381366 test_options : None ,
13391367 #[ cfg( feature = "tracing-unstable" ) ]
13401368 tracing_max_document_length_bytes : None ,
1369+ srv_max_hosts : conn_str. srv_max_hosts ,
13411370 }
13421371 }
13431372
@@ -1721,6 +1750,26 @@ impl ConnectionString {
17211750 ConnectionStringParts :: default ( )
17221751 } ;
17231752
1753+ if let Some ( srv_max_hosts) = conn_str. srv_max_hosts {
1754+ if !srv {
1755+ return Err ( Error :: invalid_argument (
1756+ "srvMaxHosts cannot be specified with a non-SRV URI" ,
1757+ ) ) ;
1758+ }
1759+ if srv_max_hosts > 0 {
1760+ if conn_str. replica_set . is_some ( ) {
1761+ return Err ( Error :: invalid_argument (
1762+ "srvMaxHosts and replicaSet cannot both be present" ,
1763+ ) ) ;
1764+ }
1765+ if conn_str. load_balanced == Some ( true ) {
1766+ return Err ( Error :: invalid_argument (
1767+ "srvMaxHosts and loadBalanced=true cannot both be present" ,
1768+ ) ) ;
1769+ }
1770+ }
1771+ }
1772+
17241773 // Set username and password.
17251774 if let Some ( u) = username {
17261775 let credential = conn_str. credential . get_or_insert_with ( Default :: default) ;
@@ -2147,6 +2196,9 @@ impl ConnectionString {
21472196 k @ "sockettimeoutms" => {
21482197 self . socket_timeout = Some ( Duration :: from_millis ( get_duration ! ( value, k) ) ) ;
21492198 }
2199+ k @ "srvmaxhosts" => {
2200+ self . srv_max_hosts = Some ( get_u32 ! ( value, k) ) ;
2201+ }
21502202 k @ "tls" | k @ "ssl" => {
21512203 let tls = get_bool ! ( value, k) ;
21522204
0 commit comments