Skip to content

Commit 297fcd7

Browse files
committed
CSHARP-3057: Reduce race conditions in SDAM error handling
1 parent 229a273 commit 297fcd7

File tree

172 files changed

+15248
-167
lines changed

Some content is hidden

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

172 files changed

+15248
-167
lines changed

src/MongoDB.Driver.Core/Core/Clusters/MultiServerCluster.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -383,7 +383,7 @@ private ClusterDescription ProcessReplicaSetChange(ClusterDescription clusterDes
383383
lock (_serversLock)
384384
{
385385
var server = _servers.SingleOrDefault(x => EndPointHelper.Equals(args.NewServerDescription.EndPoint, x.EndPoint));
386-
server.Invalidate("ReportedPrimaryIsStale");
386+
server.Invalidate("ReportedPrimaryIsStale", args.NewServerDescription.TopologyVersion);
387387

388388
_sdamInformationEventHandler?.Invoke(new SdamInformationEvent(() =>
389389
string.Format(
@@ -487,7 +487,7 @@ private ClusterDescription ProcessReplicaSetChange(ClusterDescription clusterDes
487487
foreach (var currentPrimary in currentPrimaries)
488488
{
489489
// kick off the server to invalidate itself
490-
currentPrimary.Invalidate("NoLongerPrimary");
490+
currentPrimary.Invalidate("NoLongerPrimary", args.NewServerDescription.TopologyVersion);
491491
// set it to disconnected in the cluster
492492
clusterDescription = clusterDescription.WithServerDescription(
493493
new ServerDescription(currentPrimary.ServerId, currentPrimary.EndPoint, "NoLongerPrimary"));

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

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -318,7 +318,7 @@ private async Task EnsureMinSizeAsync(CancellationToken cancellationToken)
318318

319319
var stopwatch = Stopwatch.StartNew();
320320
var connection = CreateNewConnection();
321-
// when adding in a connection, we need to open it because
321+
// when adding in a connection, we need to open it because
322322
// the whole point of having a min pool size is to have
323323
// them available and ready...
324324
try
@@ -563,6 +563,11 @@ public EndPoint EndPoint
563563
get { return _connection.EndPoint; }
564564
}
565565

566+
public int Generation
567+
{
568+
get { return _generation; }
569+
}
570+
566571
public bool IsExpired
567572
{
568573
get { return _generation < _connectionPool.Generation || _connection.IsExpired; }
@@ -636,6 +641,11 @@ public EndPoint EndPoint
636641
get { return _reference.Instance.EndPoint; }
637642
}
638643

644+
public int Generation
645+
{
646+
get { return _reference.Instance.Generation; }
647+
}
648+
639649
public bool IsExpired
640650
{
641651
get

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

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,14 @@ namespace MongoDB.Driver.Core.ConnectionPools
3131
public interface IConnectionPool : IDisposable
3232
{
3333
// properties
34+
/// <summary>
35+
/// Gets the generation of the connection pool.
36+
/// </summary>
37+
/// <value>
38+
/// The generation.
39+
/// </value>
40+
int Generation { get; }
41+
3442
/// <summary>
3543
/// Gets the server identifier.
3644
/// </summary>

src/MongoDB.Driver.Core/Core/Connections/BinaryConnection.cs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -126,6 +126,11 @@ public EndPoint EndPoint
126126
get { return _endPoint; }
127127
}
128128

129+
public int Generation
130+
{
131+
get => throw new NotSupportedException();
132+
}
133+
129134
public bool IsExpired
130135
{
131136
get

src/MongoDB.Driver.Core/Core/Connections/IConnection.cs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,14 @@ public interface IConnection : IDisposable
5757
/// </value>
5858
EndPoint EndPoint { get; }
5959

60+
/// <summary>
61+
/// Gets the generation of the pool when this connection was created.
62+
/// </summary>
63+
/// <value>
64+
/// The generation of the pool when this connection was created.
65+
/// </value>
66+
int Generation { get; }
67+
6068
/// <summary>
6169
/// Gets a value indicating whether this instance is expired.
6270
/// </summary>

src/MongoDB.Driver.Core/Core/Connections/IsMasterResult.cs

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -364,6 +364,25 @@ public TagSet Tags
364364
}
365365
}
366366

367+
/// <summary>
368+
/// Get the TopologyVersion.
369+
/// </summary>
370+
/// <value>
371+
/// Null if TopologyVersion was not included in the isMaster response.
372+
/// </value>
373+
public TopologyVersion TopologyVersion
374+
{
375+
get
376+
{
377+
if (_wrapped.TryGetValue("topologyVersion", out var topologyVersionValue) &&
378+
topologyVersionValue is BsonDocument topologyVersion)
379+
{
380+
return Servers.TopologyVersion.FromBsonDocument(topologyVersion);
381+
}
382+
return null;
383+
}
384+
}
385+
367386
/// <summary>
368387
/// Gets the maximum wire version.
369388
/// </summary>

src/MongoDB.Driver.Core/Core/Servers/IServer.cs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -103,8 +103,16 @@ public interface IClusterableServer : IServer, IDisposable
103103
/// Invalidates this instance (sets the server type to Unknown and clears the connection pool).
104104
/// </summary>
105105
/// <param name="reasonInvalidated">The reason the instance was invalidated.</param>
106+
[Obsolete("Use Invalidate with TopologyVersion instead.")]
106107
void Invalidate(string reasonInvalidated);
107108

109+
/// <summary>
110+
/// Invalidates this instance (sets the server type to Unknown and clears the connection pool).
111+
/// </summary>
112+
/// <param name="reasonInvalidated">The reason the instance was invalidated.</param>
113+
/// <param name="responseTopologyVersion">The topology of the version of the response that invalidated this instance.</param>
114+
void Invalidate(string reasonInvalidated, TopologyVersion responseTopologyVersion);
115+
108116
/// <summary>
109117
/// Requests a heartbeat as soon as possible.
110118
/// </summary>

src/MongoDB.Driver.Core/Core/Servers/IServerMonitor.cs

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,9 @@ namespace MongoDB.Driver.Core.Servers
2323
/// <seealso cref="System.IDisposable" />
2424
internal interface IServerMonitor : IDisposable
2525
{
26+
/// <summary>
27+
/// The monitor's view of the server, which could be considered stale relative to the <see cref="Server"/>'s view.
28+
/// </summary>
2629
ServerDescription Description { get; }
2730

2831
/// <summary>
@@ -35,12 +38,6 @@ internal interface IServerMonitor : IDisposable
3538
/// </summary>
3639
void Initialize();
3740

38-
/// <summary>
39-
/// Instructs the monitor to refresh its description immediately.
40-
/// </summary>
41-
/// <param name="reasonInvalidated">The reason the server was invalidated.</param>
42-
void Invalidate(string reasonInvalidated);
43-
4441
/// <summary>
4542
/// Requests a heartbeat as soon as possible.
4643
/// </summary>

0 commit comments

Comments
 (0)