Skip to content

Commit 661bcd3

Browse files
CSHARP-3952: Make maxConnecting configurable. (#678)
CSHARP-3952: Make maxConnecting configurable.
1 parent 0ad4535 commit 661bcd3

23 files changed

+422
-42
lines changed

src/MongoDB.Driver.Core/Core/Configuration/ClusterBuilderExtensions.cs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -185,6 +185,10 @@ public static ClusterBuilder ConfigureWithConnectionString(
185185
}
186186

187187
// Connection Pool
188+
if (connectionString.MaxConnecting.HasValue)
189+
{
190+
builder = builder.ConfigureConnectionPool(s => s.With(maxConnecting: connectionString.MaxConnecting.Value));
191+
}
188192
if (connectionString.MaxPoolSize != null)
189193
{
190194
var effectiveMaxConnections = ConnectionStringConversions.GetEffectiveMaxConnections(connectionString.MaxPoolSize.Value);

src/MongoDB.Driver.Core/Core/Configuration/ConnectionPoolSettings.cs

Lines changed: 22 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,6 @@
1515

1616
using System;
1717
using MongoDB.Driver.Core.Misc;
18-
using MongoDB.Shared;
1918

2019
namespace MongoDB.Driver.Core.Configuration
2120
{
@@ -42,17 +41,20 @@ public class ConnectionPoolSettings
4241
/// <param name="minConnections">The minimum number of connections.</param>
4342
/// <param name="waitQueueSize">Size of the wait queue.</param>
4443
/// <param name="waitQueueTimeout">The wait queue timeout.</param>
44+
/// <param name="maxConnecting">The maximum concurrently connecting connections.</param>
4545
public ConnectionPoolSettings(
4646
Optional<TimeSpan> maintenanceInterval = default(Optional<TimeSpan>),
4747
Optional<int> maxConnections = default(Optional<int>),
4848
Optional<int> minConnections = default(Optional<int>),
4949
Optional<int> waitQueueSize = default(Optional<int>),
50-
Optional<TimeSpan> waitQueueTimeout = default(Optional<TimeSpan>))
50+
Optional<TimeSpan> waitQueueTimeout = default(Optional<TimeSpan>),
51+
Optional<int> maxConnecting = default(Optional<int>))
5152
: this(maintenanceInterval: maintenanceInterval,
5253
maxConnections: maxConnections,
5354
minConnections: minConnections,
5455
waitQueueSize: waitQueueSize,
5556
waitQueueTimeout: waitQueueTimeout,
57+
maxConnecting: maxConnecting,
5658
isPausable: true)
5759
{
5860
}
@@ -91,6 +93,17 @@ public TimeSpan MaintenanceInterval
9193
get { return _maintenanceInterval; }
9294
}
9395

96+
/// <summary>
97+
/// Gets the maximum number of connections a pool may be establishing concurrently. Defaults to 2.
98+
/// </summary>
99+
/// <value>
100+
/// The maximum concurrently connecting connections.
101+
/// </value>
102+
public int MaxConnecting
103+
{
104+
get { return _maxConnecting; }
105+
}
106+
94107
/// <summary>
95108
/// Gets the maximum number of connections.
96109
/// </summary>
@@ -137,11 +150,6 @@ public TimeSpan WaitQueueTimeout
137150
}
138151

139152
// internal properties
140-
internal int MaxConnecting
141-
{
142-
get { return _maxConnecting; }
143-
}
144-
145153
internal bool IsPausable
146154
{
147155
get { return _isPausable; }
@@ -152,6 +160,7 @@ internal bool IsPausable
152160
/// Returns a new ConnectionPoolSettings instance with some settings changed.
153161
/// </summary>
154162
/// <param name="maintenanceInterval">The maintenance interval.</param>
163+
/// <param name="maxConnecting">The maximum concurrently connecting connections.</param>
155164
/// <param name="maxConnections">The maximum connections.</param>
156165
/// <param name="minConnections">The minimum connections.</param>
157166
/// <param name="waitQueueSize">Size of the wait queue.</param>
@@ -162,26 +171,26 @@ public ConnectionPoolSettings With(
162171
Optional<int> maxConnections = default(Optional<int>),
163172
Optional<int> minConnections = default(Optional<int>),
164173
Optional<int> waitQueueSize = default(Optional<int>),
165-
Optional<TimeSpan> waitQueueTimeout = default(Optional<TimeSpan>))
174+
Optional<TimeSpan> waitQueueTimeout = default(Optional<TimeSpan>),
175+
Optional<int> maxConnecting = default(Optional<int>))
166176
{
167177
return new ConnectionPoolSettings(
168178
maintenanceInterval: maintenanceInterval.WithDefault(_maintenanceInterval),
169179
maxConnections: maxConnections.WithDefault(_maxConnections),
170180
minConnections: minConnections.WithDefault(_minConnections),
171181
waitQueueSize: waitQueueSize.WithDefault(_waitQueueSize),
172-
waitQueueTimeout: waitQueueTimeout.WithDefault(_waitQueueTimeout));
182+
waitQueueTimeout: waitQueueTimeout.WithDefault(_waitQueueTimeout),
183+
maxConnecting: maxConnecting.WithDefault(_maxConnecting));
173184
}
174185

175-
internal ConnectionPoolSettings WithInternal(
176-
Optional<bool> isPausable = default(Optional<bool>),
177-
Optional<int> maxConnecting = default(Optional<int>)) =>
186+
internal ConnectionPoolSettings WithInternal(Optional<bool> isPausable = default(Optional<bool>)) =>
178187
new ConnectionPoolSettings(
179188
maintenanceInterval: _maintenanceInterval,
180189
maxConnections: _maxConnections,
181190
minConnections: _minConnections,
182191
waitQueueSize: _waitQueueSize,
183192
waitQueueTimeout: _waitQueueTimeout,
184193
isPausable: isPausable.WithDefault(_isPausable),
185-
maxConnecting: maxConnecting.WithDefault(_maxConnecting));
194+
maxConnecting: _maxConnecting);
186195
}
187196
}

src/MongoDB.Driver.Core/Core/Configuration/ConnectionString.cs

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,7 @@ public sealed class ConnectionString
8484
private bool? _journal;
8585
private bool _loadBalanced;
8686
private TimeSpan? _localThreshold;
87+
private int? _maxConnecting;
8788
private TimeSpan? _maxIdleTime;
8889
private TimeSpan? _maxLifeTime;
8990
private int? _maxPoolSize;
@@ -333,6 +334,14 @@ public TimeSpan? LocalThreshold
333334
get { return _localThreshold; }
334335
}
335336

337+
/// <summary>
338+
/// Gets the maximum number of connections a pool may be establishing concurrently. Defaults to 2.
339+
/// </summary>
340+
public int? MaxConnecting
341+
{
342+
get { return _maxConnecting; }
343+
}
344+
336345
/// <summary>
337346
/// Gets the max idle time.
338347
/// </summary>
@@ -984,6 +993,9 @@ private void ParseOption(string name, string value)
984993
case "loadbalanced":
985994
_loadBalanced = ParseBoolean(name, value);
986995
break;
996+
case "maxconnecting":
997+
_maxConnecting = ParseInt32(name, value);
998+
break;
987999
case "maxidletime":
9881000
case "maxidletimems":
9891001
_maxIdleTime = ParseTimeSpan(name, value);

src/MongoDB.Driver.Legacy/MongoServerSettings.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1204,6 +1204,7 @@ internal ClusterKey ToClusterKey()
12041204
kmsProviders: null, // not supported for legacy
12051205
loadBalanced: false, // not supported for legacy, so turn it off
12061206
_localThreshold,
1207+
maxConnecting: MongoInternalDefaults.ConnectionPool.MaxConnecting,
12071208
_maxConnectionIdleTime,
12081209
_maxConnectionLifeTime,
12091210
_maxConnectionPoolSize,

src/MongoDB.Driver/ClusterKey.cs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@ internal class ClusterKey
4545
private readonly IReadOnlyDictionary<string, IReadOnlyDictionary<string, object>> _kmsProviders;
4646
private readonly bool _loadBalanced;
4747
private readonly TimeSpan _localThreshold;
48+
private readonly int _maxConnecting;
4849
private readonly TimeSpan _maxConnectionIdleTime;
4950
private readonly TimeSpan _maxConnectionLifeTime;
5051
private readonly int _maxConnectionPoolSize;
@@ -83,6 +84,7 @@ public ClusterKey(
8384
IReadOnlyDictionary<string, IReadOnlyDictionary<string, object>> kmsProviders,
8485
bool loadBalanced,
8586
TimeSpan localThreshold,
87+
int maxConnecting,
8688
TimeSpan maxConnectionIdleTime,
8789
TimeSpan maxConnectionLifeTime,
8890
int maxConnectionPoolSize,
@@ -119,6 +121,7 @@ public ClusterKey(
119121
_kmsProviders = kmsProviders;
120122
_loadBalanced = loadBalanced;
121123
_localThreshold = localThreshold;
124+
_maxConnecting = maxConnecting;
122125
_maxConnectionIdleTime = maxConnectionIdleTime;
123126
_maxConnectionLifeTime = maxConnectionLifeTime;
124127
_maxConnectionPoolSize = maxConnectionPoolSize;
@@ -181,6 +184,7 @@ public bool? DirectConnection
181184
public IReadOnlyDictionary<string, IReadOnlyDictionary<string, object>> KmsProviders { get { return _kmsProviders; } }
182185
public bool LoadBalanced => _loadBalanced;
183186
public TimeSpan LocalThreshold { get { return _localThreshold; } }
187+
public int MaxConnecting{ get { return _maxConnecting; } }
184188
public TimeSpan MaxConnectionIdleTime { get { return _maxConnectionIdleTime; } }
185189
public TimeSpan MaxConnectionLifeTime { get { return _maxConnectionLifeTime; } }
186190
public int MaxConnectionPoolSize { get { return _maxConnectionPoolSize; } }
@@ -234,6 +238,7 @@ public override bool Equals(object obj)
234238
KmsProvidersHelper.Equals(_kmsProviders, rhs.KmsProviders) &&
235239
_loadBalanced == rhs._loadBalanced &&
236240
_localThreshold == rhs._localThreshold &&
241+
_maxConnecting == rhs._maxConnecting &&
237242
_maxConnectionIdleTime == rhs._maxConnectionIdleTime &&
238243
_maxConnectionLifeTime == rhs._maxConnectionLifeTime &&
239244
_maxConnectionPoolSize == rhs._maxConnectionPoolSize &&

src/MongoDB.Driver/ClusterRegistry.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,7 @@ private ConnectionPoolSettings ConfigureConnectionPool(ConnectionPoolSettings se
106106
{
107107
return settings.With(
108108
// maintenanceInterval: TODO: should this be configurable?
109+
maxConnecting: clusterKey.MaxConnecting,
109110
maxConnections: clusterKey.MaxConnectionPoolSize,
110111
minConnections: clusterKey.MinConnectionPoolSize,
111112
waitQueueSize: clusterKey.WaitQueueSize,

src/MongoDB.Driver/MongoClientSettings.cs

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,7 @@ public class MongoClientSettings : IEquatable<MongoClientSettings>, IInheritable
5353
private LinqProvider _linqProvider;
5454
private bool _loadBalanced;
5555
private TimeSpan _localThreshold;
56+
private int _maxConnecting;
5657
private TimeSpan _maxConnectionIdleTime;
5758
private TimeSpan _maxConnectionLifeTime;
5859
private int _maxConnectionPoolSize;
@@ -110,6 +111,7 @@ public MongoClientSettings()
110111
_linqProvider = LinqProvider.V2;
111112
_loadBalanced = false;
112113
_localThreshold = MongoDefaults.LocalThreshold;
114+
_maxConnecting = MongoInternalDefaults.ConnectionPool.MaxConnecting;
113115
_maxConnectionIdleTime = MongoDefaults.MaxConnectionIdleTime;
114116
_maxConnectionLifeTime = MongoDefaults.MaxConnectionLifeTime;
115117
_maxConnectionPoolSize = MongoDefaults.MaxConnectionPoolSize;
@@ -444,6 +446,19 @@ public TimeSpan LocalThreshold
444446
}
445447
}
446448

449+
/// <summary>
450+
/// Gets or sets the maximum concurrently connecting connections.
451+
/// </summary>
452+
public int MaxConnecting
453+
{
454+
get { return _maxConnecting; }
455+
set
456+
{
457+
ThrowIfFrozen();
458+
_maxConnecting = Ensure.IsGreaterThanZero(value, nameof(MaxConnecting));
459+
}
460+
}
461+
447462
/// <summary>
448463
/// Gets or sets the max connection idle time.
449464
/// </summary>
@@ -903,6 +918,7 @@ public static MongoClientSettings FromUrl(MongoUrl url)
903918
clientSettings.LinqProvider = LinqProvider.V2;
904919
clientSettings.LoadBalanced = url.LoadBalanced;
905920
clientSettings.LocalThreshold = url.LocalThreshold;
921+
clientSettings.MaxConnecting = url.MaxConnecting;
906922
clientSettings.MaxConnectionIdleTime = url.MaxConnectionIdleTime;
907923
clientSettings.MaxConnectionLifeTime = url.MaxConnectionLifeTime;
908924
clientSettings.MaxConnectionPoolSize = ConnectionStringConversions.GetEffectiveMaxConnections(url.MaxConnectionPoolSize);
@@ -957,6 +973,7 @@ public MongoClientSettings Clone()
957973
clone._linqProvider = _linqProvider;
958974
clone._loadBalanced = _loadBalanced;
959975
clone._localThreshold = _localThreshold;
976+
clone._maxConnecting = _maxConnecting;
960977
clone._maxConnectionIdleTime = _maxConnectionIdleTime;
961978
clone._maxConnectionLifeTime = _maxConnectionLifeTime;
962979
clone._maxConnectionPoolSize = _maxConnectionPoolSize;
@@ -1023,6 +1040,7 @@ public override bool Equals(object obj)
10231040
_linqProvider == rhs._linqProvider &&
10241041
_loadBalanced == rhs._loadBalanced &&
10251042
_localThreshold == rhs._localThreshold &&
1043+
_maxConnecting == rhs._maxConnecting &&
10261044
_maxConnectionIdleTime == rhs._maxConnectionIdleTime &&
10271045
_maxConnectionLifeTime == rhs._maxConnectionLifeTime &&
10281046
_maxConnectionPoolSize == rhs._maxConnectionPoolSize &&
@@ -1106,6 +1124,7 @@ public override int GetHashCode()
11061124
.Hash(_ipv6)
11071125
.Hash(_loadBalanced)
11081126
.Hash(_localThreshold)
1127+
.Hash(_maxConnecting)
11091128
.Hash(_maxConnectionIdleTime)
11101129
.Hash(_maxConnectionLifeTime)
11111130
.Hash(_maxConnectionPoolSize)
@@ -1175,6 +1194,7 @@ public override string ToString()
11751194
sb.AppendFormat("LoadBalanced={0};", _loadBalanced);
11761195
}
11771196
sb.AppendFormat("LocalThreshold={0};", _localThreshold);
1197+
sb.AppendFormat("MaxConnecting={0};", _maxConnecting);
11781198
sb.AppendFormat("MaxConnectionIdleTime={0};", _maxConnectionIdleTime);
11791199
sb.AppendFormat("MaxConnectionLifeTime={0};", _maxConnectionLifeTime);
11801200
sb.AppendFormat("MaxConnectionPoolSize={0};", _maxConnectionPoolSize);
@@ -1238,6 +1258,7 @@ internal ClusterKey ToClusterKey()
12381258
_autoEncryptionOptions?.KmsProviders,
12391259
_loadBalanced,
12401260
_localThreshold,
1261+
_maxConnecting,
12411262
_maxConnectionIdleTime,
12421263
_maxConnectionLifeTime,
12431264
_maxConnectionPoolSize,
@@ -1258,6 +1279,15 @@ internal ClusterKey ToClusterKey()
12581279
_waitQueueTimeout);
12591280
}
12601281

1282+
// private methods
1283+
private void ThrowIfFrozen()
1284+
{
1285+
if (_isFrozen)
1286+
{
1287+
throw new InvalidOperationException($"{nameof(MongoClientSettings)} is frozen.");
1288+
}
1289+
}
1290+
12611291
private void ThrowIfSettingsAreInvalid()
12621292
{
12631293
if (_allowInsecureTls && _sslSettings != null && _sslSettings.CheckCertificateRevocation)

src/MongoDB.Driver/MongoUrl.cs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,7 @@ public class MongoUrl : IEquatable<MongoUrl>
5757
private readonly bool _isResolved;
5858
private readonly bool? _journal;
5959
private readonly bool _loadBalanced;
60+
private readonly int _maxConnecting;
6061
private readonly TimeSpan _maxConnectionIdleTime;
6162
private readonly TimeSpan _maxConnectionLifeTime;
6263
private readonly int _maxConnectionPoolSize;
@@ -128,6 +129,7 @@ public MongoUrl(string url)
128129
_journal = builder.Journal;
129130
_loadBalanced = builder.LoadBalanced;
130131
_localThreshold = builder.LocalThreshold;
132+
_maxConnecting = builder.MaxConnecting;
131133
_maxConnectionIdleTime = builder.MaxConnectionIdleTime;
132134
_maxConnectionLifeTime = builder.MaxConnectionLifeTime;
133135
_maxConnectionPoolSize = builder.MaxConnectionPoolSize;
@@ -384,6 +386,14 @@ public TimeSpan LocalThreshold
384386
get { return _localThreshold; }
385387
}
386388

389+
/// <summary>
390+
/// Gets the maximum concurrently connecting connections.
391+
/// </summary>
392+
public int MaxConnecting
393+
{
394+
get { return _maxConnecting; }
395+
}
396+
387397
/// <summary>
388398
/// Gets the max connection idle time.
389399
/// </summary>

src/MongoDB.Driver/MongoUrlBuilder.cs

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,6 @@
2525
using MongoDB.Driver.Core.Compression;
2626
using MongoDB.Driver.Core.Configuration;
2727
using MongoDB.Driver.Core.Misc;
28-
using MongoDB.Shared;
2928

3029
namespace MongoDB.Driver
3130
{
@@ -59,6 +58,7 @@ public class MongoUrlBuilder
5958
private TimeSpan _localThreshold;
6059
private TimeSpan _maxConnectionIdleTime;
6160
private TimeSpan _maxConnectionLifeTime;
61+
private int _maxConnecting;
6262
private int _maxConnectionPoolSize;
6363
private int _minConnectionPoolSize;
6464
private string _password;
@@ -112,6 +112,7 @@ public MongoUrlBuilder()
112112
_journal = null;
113113
_loadBalanced = false;
114114
_localThreshold = MongoDefaults.LocalThreshold;
115+
_maxConnecting = MongoInternalDefaults.ConnectionPool.MaxConnecting;
115116
_maxConnectionIdleTime = MongoDefaults.MaxConnectionIdleTime;
116117
_maxConnectionLifeTime = MongoDefaults.MaxConnectionLifeTime;
117118
_maxConnectionPoolSize = MongoDefaults.MaxConnectionPoolSize;
@@ -434,6 +435,18 @@ public TimeSpan LocalThreshold
434435
}
435436
}
436437

438+
/// <summary>
439+
/// Gets or sets the maximum concurrently connecting connections.
440+
/// </summary>
441+
public int MaxConnecting
442+
{
443+
get { return _maxConnecting; }
444+
set
445+
{
446+
_maxConnecting = Ensure.IsGreaterThanZero(value, nameof(MaxConnecting));
447+
}
448+
}
449+
437450
/// <summary>
438451
/// Gets or sets the max connection idle time.
439452
/// </summary>
@@ -831,6 +844,7 @@ public void Parse(string url)
831844
_journal = connectionString.Journal;
832845
_loadBalanced = connectionString.LoadBalanced;
833846
_localThreshold = connectionString.LocalThreshold.GetValueOrDefault(MongoDefaults.LocalThreshold);
847+
_maxConnecting = connectionString.MaxConnecting.GetValueOrDefault(MongoInternalDefaults.ConnectionPool.MaxConnecting);
834848
_maxConnectionIdleTime = connectionString.MaxIdleTime.GetValueOrDefault(MongoDefaults.MaxConnectionIdleTime);
835849
_maxConnectionLifeTime = connectionString.MaxLifeTime.GetValueOrDefault(MongoDefaults.MaxConnectionLifeTime);
836850
_maxConnectionPoolSize = connectionString.MaxPoolSize.GetValueOrDefault(MongoDefaults.MaxConnectionPoolSize);
@@ -1084,6 +1098,10 @@ public override string ToString()
10841098
{
10851099
query.AppendFormat("localThreshold={0};", FormatTimeSpan(_localThreshold));
10861100
}
1101+
if (_maxConnecting != MongoInternalDefaults.ConnectionPool.MaxConnecting)
1102+
{
1103+
query.AppendFormat("maxConnecting={0};", _maxConnecting);
1104+
}
10871105
if (_maxConnectionIdleTime != MongoDefaults.MaxConnectionIdleTime)
10881106
{
10891107
query.AppendFormat("maxIdleTime={0};", FormatTimeSpan(_maxConnectionIdleTime));

0 commit comments

Comments
 (0)