Skip to content

Commit ebf2d57

Browse files
CSHARP-2427: Implement Connection Monitoring and Pooling.
1 parent 604c1d3 commit ebf2d57

File tree

111 files changed

+3009
-83
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

111 files changed

+3009
-83
lines changed

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

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -136,6 +136,7 @@ public static ClusterBuilder ConfigureWithConnectionString(this ClusterBuilder b
136136
{
137137
builder = builder.ConfigureConnectionPool(s => s.With(minConnections: connectionString.MinPoolSize.Value));
138138
}
139+
#pragma warning disable 618
139140
if (connectionString.WaitQueueSize != null)
140141
{
141142
builder = builder.ConfigureConnectionPool(s => s.With(waitQueueSize: connectionString.WaitQueueSize.Value));
@@ -146,6 +147,7 @@ public static ClusterBuilder ConfigureWithConnectionString(this ClusterBuilder b
146147
var waitQueueSize = (int)Math.Round(maxConnections * connectionString.WaitQueueMultiple.Value);
147148
builder = builder.ConfigureConnectionPool(s => s.With(waitQueueSize: waitQueueSize));
148149
}
150+
#pragma warning restore 618
149151
if (connectionString.WaitQueueTimeout != null)
150152
{
151153
builder = builder.ConfigureConnectionPool(s => s.With(waitQueueTimeout: connectionString.WaitQueueTimeout.Value));

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,7 @@ public int MinConnections
9393
/// <value>
9494
/// The size of the wait queue.
9595
/// </value>
96+
[Obsolete("This property will be removed in a later release.")]
9697
public int WaitQueueSize
9798
{
9899
get { return _waitQueueSize; }

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

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -451,6 +451,7 @@ public GuidRepresentation? UuidRepresentation
451451
/// <summary>
452452
/// Gets the wait queue multiple.
453453
/// </summary>
454+
[Obsolete("This property will be removed in a later release.")]
454455
public double? WaitQueueMultiple
455456
{
456457
get { return _waitQueueMultiple; }
@@ -459,6 +460,7 @@ public double? WaitQueueMultiple
459460
/// <summary>
460461
/// Gets the wait queue size.
461462
/// </summary>
463+
[Obsolete("This property will be removed in a later release.")]
462464
public int? WaitQueueSize
463465
{
464466
get { return _waitQueueSize; }

src/MongoDB.Driver.Core/Core/ConnectionPools/ExclusiveConnectionPool.cs

Lines changed: 48 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,9 @@ internal sealed class ExclusiveConnectionPool : IConnectionPool
5454
private readonly Action<ConnectionPoolOpenedEvent> _openedEventHandler;
5555
private readonly Action<ConnectionPoolClosingEvent> _closingEventHandler;
5656
private readonly Action<ConnectionPoolClosedEvent> _closedEventHandler;
57+
private readonly Action<ConnectionPoolClearingEvent> _clearingEventHandler;
58+
private readonly Action<ConnectionPoolClearedEvent> _clearedEventHandler;
59+
private readonly Action<ConnectionCreatedEvent> _connectionCreatedEventHandler;
5760

5861
// constructors
5962
public ExclusiveConnectionPool(
@@ -71,7 +74,9 @@ public ExclusiveConnectionPool(
7174

7275
_connectionHolder = new ListConnectionHolder(eventSubscriber);
7376
_poolQueue = new WaitQueue(settings.MaxConnections);
77+
#pragma warning disable 618
7478
_waitQueue = new SemaphoreSlim(settings.WaitQueueSize);
79+
#pragma warning restore 618
7580
_maintenanceCancellationTokenSource = new CancellationTokenSource();
7681
_state = new InterlockedInt32(State.Initial);
7782

@@ -88,6 +93,9 @@ public ExclusiveConnectionPool(
8893
eventSubscriber.TryGetEventHandler(out _closedEventHandler);
8994
eventSubscriber.TryGetEventHandler(out _addingConnectionEventHandler);
9095
eventSubscriber.TryGetEventHandler(out _addedConnectionEventHandler);
96+
eventSubscriber.TryGetEventHandler(out _clearingEventHandler);
97+
eventSubscriber.TryGetEventHandler(out _clearedEventHandler);
98+
eventSubscriber.TryGetEventHandler(out _connectionCreatedEventHandler);
9199
}
92100

93101
// properties
@@ -140,12 +148,12 @@ public int UsedCount
140148
// public methods
141149
public IConnectionHandle AcquireConnection(CancellationToken cancellationToken)
142150
{
143-
ThrowIfNotOpen();
144-
145151
var helper = new AcquireConnectionHelper(this);
146152
try
147153
{
148154
helper.CheckingOutConnection();
155+
ThrowIfNotOpen();
156+
helper.EnterWaitQueue();
149157
var enteredPool = _poolQueue.Wait(_settings.WaitQueueTimeout, cancellationToken);
150158
return helper.EnteredPool(enteredPool);
151159
}
@@ -162,12 +170,12 @@ public IConnectionHandle AcquireConnection(CancellationToken cancellationToken)
162170

163171
public async Task<IConnectionHandle> AcquireConnectionAsync(CancellationToken cancellationToken)
164172
{
165-
ThrowIfNotOpen();
166-
167173
var helper = new AcquireConnectionHelper(this);
168174
try
169175
{
170176
helper.CheckingOutConnection();
177+
ThrowIfNotOpen();
178+
helper.EnterWaitQueue();
171179
var enteredPool = await _poolQueue.WaitAsync(_settings.WaitQueueTimeout, cancellationToken).ConfigureAwait(false);
172180
return helper.EnteredPool(enteredPool);
173181
}
@@ -185,13 +193,20 @@ public async Task<IConnectionHandle> AcquireConnectionAsync(CancellationToken ca
185193
public void Clear()
186194
{
187195
ThrowIfNotOpen();
196+
197+
_clearingEventHandler?.Invoke(new ConnectionPoolClearingEvent(_serverId, _settings));
198+
188199
Interlocked.Increment(ref _generation);
200+
201+
_clearedEventHandler?.Invoke(new ConnectionPoolClearedEvent(_serverId, _settings));
189202
}
190203

191204
private PooledConnection CreateNewConnection()
192205
{
193206
var connection = _connectionFactory.CreateConnection(_serverId, _endPoint);
194-
return new PooledConnection(this, connection);
207+
var pooledConnection = new PooledConnection(this, connection);
208+
_connectionCreatedEventHandler?.Invoke(new ConnectionCreatedEvent(connection.ConnectionId, connection.Settings, EventContext.OperationId));
209+
return pooledConnection;
195210
}
196211

197212
public void Initialize()
@@ -204,12 +219,12 @@ public void Initialize()
204219
_openingEventHandler(new ConnectionPoolOpeningEvent(_serverId, _settings));
205220
}
206221

207-
MaintainSizeAsync().ConfigureAwait(false);
208-
209222
if (_openedEventHandler != null)
210223
{
211224
_openedEventHandler(new ConnectionPoolOpenedEvent(_serverId, _settings));
212225
}
226+
227+
MaintainSizeAsync().ConfigureAwait(false);
213228
}
214229
}
215230

@@ -335,25 +350,28 @@ private async Task EnsureMinSizeAsync(CancellationToken cancellationToken)
335350

336351
private void ReleaseConnection(PooledConnection connection)
337352
{
338-
if (_state.Value == State.Disposed)
353+
if (_checkingInConnectionEventHandler != null)
339354
{
340-
connection.Dispose();
341-
return;
355+
_checkingInConnectionEventHandler(new ConnectionPoolCheckingInConnectionEvent(connection.ConnectionId, EventContext.OperationId));
342356
}
343357

344-
if (_checkingInConnectionEventHandler != null)
358+
if (_checkedInConnectionEventHandler != null)
345359
{
346-
_checkingInConnectionEventHandler(new ConnectionPoolCheckingInConnectionEvent(connection.ConnectionId, EventContext.OperationId));
360+
_checkedInConnectionEventHandler(new ConnectionPoolCheckedInConnectionEvent(connection.ConnectionId, TimeSpan.Zero, EventContext.OperationId));
347361
}
348362

349-
var stopwatch = Stopwatch.StartNew();
350-
_connectionHolder.Return(connection);
351-
_poolQueue.Release();
352-
stopwatch.Stop();
363+
if (!connection.IsExpired && _state.Value != State.Disposed)
364+
{
365+
_connectionHolder.Return(connection);
366+
}
367+
else
368+
{
369+
_connectionHolder.RemoveConnection(connection);
370+
}
353371

354-
if (_checkedInConnectionEventHandler != null)
372+
if (_state.Value != State.Disposed)
355373
{
356-
_checkedInConnectionEventHandler(new ConnectionPoolCheckedInConnectionEvent(connection.ConnectionId, stopwatch.Elapsed, EventContext.OperationId));
374+
_poolQueue.Release();
357375
}
358376
}
359377

@@ -404,7 +422,10 @@ public void CheckingOutConnection()
404422
{
405423
handler(new ConnectionPoolCheckingOutConnectionEvent(_pool._serverId, EventContext.OperationId));
406424
}
425+
}
407426

427+
public void EnterWaitQueue()
428+
{
408429
_enteredWaitQueue = _pool._waitQueue.Wait(0); // don't wait...
409430
if (!_enteredWaitQueue)
410431
{
@@ -467,7 +488,14 @@ public void HandleException(Exception ex)
467488
var handler = _pool._checkingOutConnectionFailedEventHandler;
468489
if (handler != null)
469490
{
470-
handler(new ConnectionPoolCheckingOutConnectionFailedEvent(_pool._serverId, ex, EventContext.OperationId));
491+
ConnectionCheckOutFailedReason reason;
492+
switch (ex)
493+
{
494+
case ObjectDisposedException _: reason = ConnectionCheckOutFailedReason.PoolClosed; break;
495+
case TimeoutException _: reason = ConnectionCheckOutFailedReason.Timeout; break;
496+
default: reason = ConnectionCheckOutFailedReason.ConnectionError; break;
497+
}
498+
handler(new ConnectionPoolCheckingOutConnectionFailedEvent(_pool._serverId, ex, EventContext.OperationId, reason));
471499
}
472500
}
473501

@@ -788,19 +816,13 @@ public PooledConnection Acquire()
788816

789817
public void Return(PooledConnection connection)
790818
{
791-
if (connection.IsExpired)
792-
{
793-
RemoveConnection(connection);
794-
return;
795-
}
796-
797819
lock (_lock)
798820
{
799821
_connections.Add(connection);
800822
}
801823
}
802824

803-
private void RemoveConnection(PooledConnection connection)
825+
public void RemoveConnection(PooledConnection connection)
804826
{
805827
if (_removingConnectionEventHandler != null)
806828
{

src/MongoDB.Driver.Core/Core/Events/ClusterAddedServerEvent.cs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,6 @@
1919

2020
namespace MongoDB.Driver.Core.Events
2121
{
22-
/// <preliminary/>
2322
/// <summary>
2423
/// Occurs after a server is added to the cluster.
2524
/// </summary>

src/MongoDB.Driver.Core/Core/Events/ClusterAddingServerEvent.cs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,6 @@
1818

1919
namespace MongoDB.Driver.Core.Events
2020
{
21-
/// <preliminary/>
2221
/// <summary>
2322
/// Occurs before a server is added to the cluster.
2423
/// </summary>

src/MongoDB.Driver.Core/Core/Events/ClusterClosedEvent.cs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,6 @@
1818

1919
namespace MongoDB.Driver.Core.Events
2020
{
21-
/// <preliminary/>
2221
/// <summary>
2322
/// Occurs after a cluster is closed.
2423
/// </summary>

src/MongoDB.Driver.Core/Core/Events/ClusterClosingEvent.cs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,6 @@
1717

1818
namespace MongoDB.Driver.Core.Events
1919
{
20-
/// <preliminary/>
2120
/// <summary>
2221
/// Occurs before a cluster is closed.
2322
/// </summary>

src/MongoDB.Driver.Core/Core/Events/ClusterDescriptionChangedEvent.cs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,6 @@
1818

1919
namespace MongoDB.Driver.Core.Events
2020
{
21-
/// <preliminary/>
2221
/// <summary>
2322
/// Occurs when a cluster has changed.
2423
/// </summary>

src/MongoDB.Driver.Core/Core/Events/ClusterOpenedEvent.cs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,6 @@
1919

2020
namespace MongoDB.Driver.Core.Events
2121
{
22-
/// <preliminary/>
2322
/// <summary>
2423
/// Occurs after a cluster is opened.
2524
/// </summary>

0 commit comments

Comments
 (0)