From fd34bc03580e3d5b72d4c417d1d5af4fdfda0aab Mon Sep 17 00:00:00 2001 From: adelinowona Date: Wed, 10 Apr 2024 18:45:02 -0400 Subject: [PATCH 01/24] CSHARP-3757: Redirect read/write retries to other mongos if possible --- .../Core/Clusters/Cluster.cs | 54 ++++++++++++++++--- .../Core/Clusters/ICluster.cs | 19 +++++++ .../Core/Clusters/LoadBalancedCluster.cs | 8 +++ 3 files changed, 73 insertions(+), 8 deletions(-) diff --git a/src/MongoDB.Driver.Core/Core/Clusters/Cluster.cs b/src/MongoDB.Driver.Core/Core/Clusters/Cluster.cs index 14304be0297..309203d8d6d 100644 --- a/src/MongoDB.Driver.Core/Core/Clusters/Cluster.cs +++ b/src/MongoDB.Driver.Core/Core/Clusters/Cluster.cs @@ -281,6 +281,16 @@ protected void OnDescriptionChanged(ClusterDescription oldDescription, ClusterDe } public IServer SelectServer(IServerSelector selector, CancellationToken cancellationToken) + { + return SelectServer(selector, null, cancellationToken); + } + + public Task SelectServerAsync(IServerSelector selector, CancellationToken cancellationToken) + { + return SelectServerAsync(selector, null, cancellationToken); + } + + public IServer SelectServer(IServerSelector selector, IReadOnlyCollection deprioritizedServers, CancellationToken cancellationToken) { ThrowIfDisposedOrNotOpen(); Ensure.IsNotNull(selector, nameof(selector)); @@ -291,7 +301,7 @@ public IServer SelectServer(IServerSelector selector, CancellationToken cancella { while (true) { - var server = helper.SelectServer(); + var server = helper.SelectServer(deprioritizedServers); if (server != null) { return server; @@ -309,7 +319,7 @@ public IServer SelectServer(IServerSelector selector, CancellationToken cancella } } - public async Task SelectServerAsync(IServerSelector selector, CancellationToken cancellationToken) + public async Task SelectServerAsync(IServerSelector selector, IReadOnlyCollection deprioritizedServers, CancellationToken cancellationToken) { ThrowIfDisposedOrNotOpen(); Ensure.IsNotNull(selector, nameof(selector)); @@ -320,7 +330,7 @@ public async Task SelectServerAsync(IServerSelector selector, Cancellat { while (true) { - var server = helper.SelectServer(); + var server = helper.SelectServer(deprioritizedServers); if (server != null) { return server; @@ -483,7 +493,7 @@ public void HandleException(Exception exception) EventContext.OperationName)); } - public IServer SelectServer() + public IServer SelectServer(IReadOnlyCollection deprioritizedServers) { lock (_cluster._descriptionLock) { @@ -506,13 +516,41 @@ public IServer SelectServer() _connectedServers.Clear(); _connectedServerDescriptions.Clear(); + var excludingDeprioritizedServers = deprioritizedServers != null && _cluster.Description.Type == ClusterType.Sharded; + foreach (var description in _description.Servers) { - if (description.State == ServerState.Connected && - _cluster.TryGetServer(description.EndPoint, out var server)) + if (!excludingDeprioritizedServers || !deprioritizedServers.Contains(description)) + { + if (description.State == ServerState.Connected && + _cluster.TryGetServer(description.EndPoint, out var server)) + { + _connectedServers.Add(server); + _connectedServerDescriptions.Add(description); + } + } + else + { + _cluster._serverSelectionEventLogger.Logger.LogDebug(_cluster._clusterId, + $"Deprioritization: removed server {description.ServerId}"); + } + } + + // if we didn't get any connected servers from the previous look through candidates above + // and we are currently excluding deprioritized servers then it possible that all the + // candidates were part of the deprioritized collection. In this case, we just try to + // use the deprioritized servers. + if (excludingDeprioritizedServers && _connectedServers.Count == 0) + { + _cluster._serverSelectionEventLogger.Logger.LogDebug(_cluster._clusterId, "Deprioritization: reverting due to no other suitable servers"); + foreach (var description in deprioritizedServers) { - _connectedServers.Add(server); - _connectedServerDescriptions.Add(description); + if (description.State == ServerState.Connected && + _cluster.TryGetServer(description.EndPoint, out var server)) + { + _connectedServers.Add(server); + _connectedServerDescriptions.Add(description); + } } } diff --git a/src/MongoDB.Driver.Core/Core/Clusters/ICluster.cs b/src/MongoDB.Driver.Core/Core/Clusters/ICluster.cs index 1be15c516be..47fcd1d4443 100644 --- a/src/MongoDB.Driver.Core/Core/Clusters/ICluster.cs +++ b/src/MongoDB.Driver.Core/Core/Clusters/ICluster.cs @@ -14,6 +14,7 @@ */ using System; +using System.Collections.Generic; using System.Threading; using System.Threading.Tasks; using MongoDB.Driver.Core.Bindings; @@ -96,6 +97,24 @@ public interface ICluster : IDisposable /// A Task representing the operation. The result of the Task is the selected server. Task SelectServerAsync(IServerSelector selector, CancellationToken cancellationToken); + /// + /// Selects a server from the cluster while prioritizing servers not found in the provided collection of deprioritized servers. + /// + /// The server selector. + /// The deprioritized Servers. + /// The cancellation token. + /// The selected server. + IServer SelectServer(IServerSelector selector, IReadOnlyCollection deprioritizedServers, CancellationToken cancellationToken); + + /// + /// Selects a server from the cluster while prioritizing servers not found in the provided collection of deprioritized servers. + /// + /// The server selector. + /// The deprioritized Servers. + /// The cancellation token. + /// A Task representing the operation. The result of the Task is the selected server. + Task SelectServerAsync(IServerSelector selector, IReadOnlyCollection deprioritizedServers, CancellationToken cancellationToken); + /// /// Starts a session. /// diff --git a/src/MongoDB.Driver.Core/Core/Clusters/LoadBalancedCluster.cs b/src/MongoDB.Driver.Core/Core/Clusters/LoadBalancedCluster.cs index 14bcba657a5..af4e8eb9a50 100644 --- a/src/MongoDB.Driver.Core/Core/Clusters/LoadBalancedCluster.cs +++ b/src/MongoDB.Driver.Core/Core/Clusters/LoadBalancedCluster.cs @@ -256,6 +256,14 @@ public async Task SelectServerAsync(IServerSelector selector, Cancellat throw new InvalidOperationException("The server must be created before usage."); // should not be reached } + public IServer SelectServer(IServerSelector selector, IReadOnlyCollection deprioritizedServers, + CancellationToken cancellationToken) => + throw new NotImplementedException(); + + public Task SelectServerAsync(IServerSelector selector, IReadOnlyCollection deprioritizedServers, + CancellationToken cancellationToken) => + throw new NotImplementedException(); + public ICoreSessionHandle StartSession(CoreSessionOptions options = null) { ThrowIfDisposed(); From 52539e92a116f86b6cfa71bbcc5191dee8a326e6 Mon Sep 17 00:00:00 2001 From: adelinowona Date: Wed, 10 Apr 2024 18:46:55 -0400 Subject: [PATCH 02/24] Add selectServer unit tests --- .../Core/Clusters/ClusterTests.cs | 96 +++++++++++++++++++ 1 file changed, 96 insertions(+) diff --git a/tests/MongoDB.Driver.Core.Tests/Core/Clusters/ClusterTests.cs b/tests/MongoDB.Driver.Core.Tests/Core/Clusters/ClusterTests.cs index d84ab3f6465..5d2014796ac 100644 --- a/tests/MongoDB.Driver.Core.Tests/Core/Clusters/ClusterTests.cs +++ b/tests/MongoDB.Driver.Core.Tests/Core/Clusters/ClusterTests.cs @@ -413,6 +413,101 @@ public void SelectServer_should_keep_trying_to_match_by_waiting_on_cluster_descr _capturedEvents.Any().Should().BeFalse(); } + [Theory] + [ParameterAttributeData] + public void SelectServer_should_ignore_deprioritized_servers_if_cluster_is_sharded( + [Values(false, true)] + bool async) + { +#pragma warning disable CS0618 // Type or member is obsolete + var subject = CreateSubject(ClusterConnectionMode.Sharded); +#pragma warning restore CS0618 // Type or member is obsolete + + subject.Initialize(); + + var endPoint1 = new DnsEndPoint("localhost", 27017); + var endPoint2 = new DnsEndPoint("localhost", 27018); + var endPoint3 = new DnsEndPoint("localhost", 27019); + var connected1 = ServerDescriptionHelper.Connected(subject.Description.ClusterId, endPoint1); + var connected2 = ServerDescriptionHelper.Connected(subject.Description.ClusterId, endPoint2); + var connected3 = ServerDescriptionHelper.Connected(subject.Description.ClusterId, endPoint3); + subject.SetServerDescriptions(connected1, connected2, connected3); + + var selector = new DelegateServerSelector((c, s) => s); + + var deprioritizedServers = new List { connected1 }; + + for (int i = 0; i < 15; i++) + { + _capturedEvents.Clear(); + + IServer result; + if (async) + { + result = subject.SelectServerAsync(selector, deprioritizedServers, CancellationToken.None).GetAwaiter().GetResult(); + } + else + { + result = subject.SelectServer(selector, deprioritizedServers, CancellationToken.None); + } + + result.Should().NotBeNull(); + + var deprioritizedServersEndpoints = deprioritizedServers.Select(description => description.EndPoint); + deprioritizedServersEndpoints.Should().NotContain(result.Description.EndPoint); + + _capturedEvents.Next().Should().BeOfType(); + _capturedEvents.Next().Should().BeOfType(); + _capturedEvents.Any().Should().BeFalse(); + } + } + + [Theory] + [ParameterAttributeData] + public void SelectServer_should_return_deprioritized_servers_if_no_other_servers_exist_or_cluster_not_sharded( + [Values(false, true)] bool async, + [Values(false, true)] bool IsSharded) + { +#pragma warning disable CS0618 // Type or member is obsolete + StubCluster subject = IsSharded ? CreateSubject(ClusterConnectionMode.Sharded) : CreateSubject(); +#pragma warning restore CS0618 // Type or member is obsolete + + subject.Initialize(); + + var endPoint1 = new DnsEndPoint("localhost", 27017); + var endPoint2 = new DnsEndPoint("localhost", 27018); + var connected1 = ServerDescriptionHelper.Connected(subject.Description.ClusterId, endPoint1); + var connected2 = ServerDescriptionHelper.Connected(subject.Description.ClusterId, endPoint2); + subject.SetServerDescriptions(connected1, connected2); + + var selector = new DelegateServerSelector((c, s) => s); + + var deprioritizedServers = new List { connected1, connected2 }; + + for (int i = 0; i < 15; i++) + { + _capturedEvents.Clear(); + IServer result; + if (async) + { + result = subject.SelectServerAsync(selector, deprioritizedServers, CancellationToken.None).GetAwaiter().GetResult(); + } + else + { + result = subject.SelectServer(selector, deprioritizedServers, CancellationToken.None); + } + + result.Should().NotBeNull(); + + var deprioritizedServersEndpoints = deprioritizedServers.Select(description => description.EndPoint); + deprioritizedServersEndpoints.Should().Contain(result.Description.EndPoint); + + _capturedEvents.Next().Should().BeOfType(); + _capturedEvents.Next().Should().BeOfType(); + _capturedEvents.Any().Should().BeFalse(); + } + } + [Fact] public void StartSession_should_return_expected_result() { @@ -591,6 +686,7 @@ public StubCluster(ClusterSettings settings, public override void Initialize() { base.Initialize(); + UpdateClusterDescription(Description.WithType(Settings.GetInitialClusterType())); } public void RemoveServer(EndPoint endPoint) From cd47033416f45ac7373ce5f5b01bbbd92ece7ca9 Mon Sep 17 00:00:00 2001 From: adelinowona Date: Wed, 10 Apr 2024 18:51:54 -0400 Subject: [PATCH 03/24] Adds functionality for passing deprioritized servers in retries --- .../Core/Bindings/ChannelReadBinding.cs | 17 ++++-- .../Core/Bindings/ChannelReadWriteBinding.cs | 37 +++++++++++++ .../Bindings/ChannelSourceReadWriteBinding.cs | 38 +++++++++++++ .../Core/Bindings/IBinding.cs | 51 ++++++++++++++++++ .../Core/Bindings/ReadBindingHandle.cs | 18 +++++-- .../Core/Bindings/ReadPreferenceBinding.cs | 21 ++++++-- .../Core/Bindings/ReadWriteBindingHandle.cs | 47 ++++++++++++++-- .../Core/Bindings/SingleServerReadBinding.cs | 13 +++++ .../Bindings/SingleServerReadWriteBinding.cs | 37 +++++++++++++ .../Core/Bindings/WritableServerBinding.cs | 54 +++++++++++++++---- .../Core/Clusters/IClusterExtensions.cs | 7 ++- .../RetryableReadOperationExecutor.cs | 4 +- .../RetryableWriteOperationExecutor.cs | 4 +- .../Bindings/CoreServerSessionPoolTests.cs | 2 + 14 files changed, 321 insertions(+), 29 deletions(-) diff --git a/src/MongoDB.Driver.Core/Core/Bindings/ChannelReadBinding.cs b/src/MongoDB.Driver.Core/Core/Bindings/ChannelReadBinding.cs index 11b3c29c3fb..c91671dfa75 100644 --- a/src/MongoDB.Driver.Core/Core/Bindings/ChannelReadBinding.cs +++ b/src/MongoDB.Driver.Core/Core/Bindings/ChannelReadBinding.cs @@ -14,10 +14,9 @@ */ using System; +using System.Collections.Generic; using System.Threading; using System.Threading.Tasks; -using MongoDB.Driver.Core.Clusters; -using MongoDB.Driver.Core.Connections; using MongoDB.Driver.Core.Misc; using MongoDB.Driver.Core.Servers; @@ -51,7 +50,7 @@ public ChannelReadBinding(IServer server, IChannelHandle channel, ReadPreference _session = Ensure.IsNotNull(session, nameof(session)); } - // properties + // properties /// public ReadPreference ReadPreference { @@ -90,6 +89,18 @@ public Task GetReadChannelSourceAsync(CancellationToken ca return Task.FromResult(GetReadChannelSourceHelper()); } + /// + public IChannelSourceHandle GetReadChannelSource(IReadOnlyCollection deprioritizedServers, CancellationToken cancellationToken) + { + return GetReadChannelSource(cancellationToken); + } + + /// + public Task GetReadChannelSourceAsync(IReadOnlyCollection deprioritizedServers, CancellationToken cancellationToken) + { + return GetReadChannelSourceAsync(cancellationToken); + } + private IChannelSourceHandle GetReadChannelSourceHelper() { return new ChannelSourceHandle(new ChannelChannelSource(_server, _channel.Fork(), _session.Fork())); diff --git a/src/MongoDB.Driver.Core/Core/Bindings/ChannelReadWriteBinding.cs b/src/MongoDB.Driver.Core/Core/Bindings/ChannelReadWriteBinding.cs index 2375dd0560d..2e8bf6695f3 100644 --- a/src/MongoDB.Driver.Core/Core/Bindings/ChannelReadWriteBinding.cs +++ b/src/MongoDB.Driver.Core/Core/Bindings/ChannelReadWriteBinding.cs @@ -14,6 +14,7 @@ */ using System; +using System.Collections.Generic; using System.Threading; using System.Threading.Tasks; using MongoDB.Driver.Core.Misc; @@ -85,6 +86,18 @@ public Task GetReadChannelSourceAsync(CancellationToken ca return Task.FromResult(GetChannelSourceHelper()); } + /// + public IChannelSourceHandle GetReadChannelSource(IReadOnlyCollection deprioritizedServers, CancellationToken cancellationToken) + { + return GetReadChannelSource(cancellationToken); + } + + /// + public Task GetReadChannelSourceAsync(IReadOnlyCollection deprioritizedServers, CancellationToken cancellationToken) + { + return GetReadChannelSourceAsync(cancellationToken); + } + /// public IChannelSourceHandle GetWriteChannelSource(CancellationToken cancellationToken) { @@ -92,12 +105,24 @@ public IChannelSourceHandle GetWriteChannelSource(CancellationToken cancellation return GetChannelSourceHelper(); } + /// + public IChannelSourceHandle GetWriteChannelSource(IReadOnlyCollection deprioritizedServers, CancellationToken cancellationToken) + { + return GetWriteChannelSource(cancellationToken); + } + /// public IChannelSourceHandle GetWriteChannelSource(IMayUseSecondaryCriteria mayUseSecondary, CancellationToken cancellationToken) { return GetWriteChannelSource(cancellationToken); // ignore mayUseSecondary } + /// + public IChannelSourceHandle GetWriteChannelSource(IReadOnlyCollection deprioritizedServers, IMayUseSecondaryCriteria mayUseSecondary, CancellationToken cancellationToken) + { + return GetWriteChannelSource(mayUseSecondary, cancellationToken); + } + /// public Task GetWriteChannelSourceAsync(CancellationToken cancellationToken) { @@ -105,12 +130,24 @@ public Task GetWriteChannelSourceAsync(CancellationToken c return Task.FromResult(GetChannelSourceHelper()); } + /// + public Task GetWriteChannelSourceAsync(IReadOnlyCollection deprioritizedServers, CancellationToken cancellationToken) + { + return GetWriteChannelSourceAsync(cancellationToken); + } + /// public Task GetWriteChannelSourceAsync(IMayUseSecondaryCriteria mayUseSecondary, CancellationToken cancellationToken) { return GetWriteChannelSourceAsync(cancellationToken); // ignore mayUseSecondary } + /// + public Task GetWriteChannelSourceAsync(IReadOnlyCollection deprioritizedServers, IMayUseSecondaryCriteria mayUseSecondary, CancellationToken cancellationToken) + { + return GetWriteChannelSourceAsync(mayUseSecondary, cancellationToken); + } + // private methods private IChannelSourceHandle GetChannelSourceHelper() { diff --git a/src/MongoDB.Driver.Core/Core/Bindings/ChannelSourceReadWriteBinding.cs b/src/MongoDB.Driver.Core/Core/Bindings/ChannelSourceReadWriteBinding.cs index 75b8928e297..e434a36a57b 100644 --- a/src/MongoDB.Driver.Core/Core/Bindings/ChannelSourceReadWriteBinding.cs +++ b/src/MongoDB.Driver.Core/Core/Bindings/ChannelSourceReadWriteBinding.cs @@ -14,9 +14,11 @@ */ using System; +using System.Collections.Generic; using System.Threading; using System.Threading.Tasks; using MongoDB.Driver.Core.Misc; +using MongoDB.Driver.Core.Servers; namespace MongoDB.Driver.Core.Bindings { @@ -73,6 +75,18 @@ public Task GetReadChannelSourceAsync(CancellationToken ca return Task.FromResult(GetChannelSourceHelper()); } + /// + public IChannelSourceHandle GetReadChannelSource(IReadOnlyCollection deprioritizedServers, CancellationToken cancellationToken) + { + return GetReadChannelSource(cancellationToken); + } + + /// + public Task GetReadChannelSourceAsync(IReadOnlyCollection deprioritizedServers, CancellationToken cancellationToken) + { + return GetReadChannelSourceAsync(cancellationToken); + } + /// public IChannelSourceHandle GetWriteChannelSource(CancellationToken cancellationToken) { @@ -80,12 +94,24 @@ public IChannelSourceHandle GetWriteChannelSource(CancellationToken cancellation return GetChannelSourceHelper(); } + /// + public IChannelSourceHandle GetWriteChannelSource(IReadOnlyCollection deprioritizedServers, CancellationToken cancellationToken) + { + return GetWriteChannelSource(cancellationToken); + } + /// public IChannelSourceHandle GetWriteChannelSource(IMayUseSecondaryCriteria mayUseSecondary, CancellationToken cancellationToken) { return GetWriteChannelSource(cancellationToken); // ignore mayUseSecondary } + /// + public IChannelSourceHandle GetWriteChannelSource(IReadOnlyCollection deprioritizedServers, IMayUseSecondaryCriteria mayUseSecondary, CancellationToken cancellationToken) + { + return GetWriteChannelSource(mayUseSecondary, cancellationToken); + } + /// public Task GetWriteChannelSourceAsync(CancellationToken cancellationToken) { @@ -93,12 +119,24 @@ public Task GetWriteChannelSourceAsync(CancellationToken c return Task.FromResult(GetChannelSourceHelper()); } + /// + public Task GetWriteChannelSourceAsync(IReadOnlyCollection deprioritizedServers, CancellationToken cancellationToken) + { + return GetWriteChannelSourceAsync(cancellationToken); + } + /// public Task GetWriteChannelSourceAsync(IMayUseSecondaryCriteria mayUseSecondary, CancellationToken cancellationToken) { return GetWriteChannelSourceAsync(cancellationToken); // ignore mayUseSecondary } + /// + public Task GetWriteChannelSourceAsync(IReadOnlyCollection deprioritizedServers, IMayUseSecondaryCriteria mayUseSecondary, CancellationToken cancellationToken) + { + return GetWriteChannelSourceAsync(mayUseSecondary, cancellationToken); + } + /// public void Dispose() { diff --git a/src/MongoDB.Driver.Core/Core/Bindings/IBinding.cs b/src/MongoDB.Driver.Core/Core/Bindings/IBinding.cs index 1e625a04e3c..40c33ee441c 100644 --- a/src/MongoDB.Driver.Core/Core/Bindings/IBinding.cs +++ b/src/MongoDB.Driver.Core/Core/Bindings/IBinding.cs @@ -14,6 +14,7 @@ */ using System; +using System.Collections.Generic; using System.Threading; using System.Threading.Tasks; using MongoDB.Driver.Core.Servers; @@ -61,6 +62,22 @@ public interface IReadBinding : IBinding /// The cancellation token. /// A channel source. Task GetReadChannelSourceAsync(CancellationToken cancellationToken); + + /// + /// Gets a channel source for read operations while deprioritizing servers in the provided collection. + /// + /// The deprioritized servers. + /// The cancellation token. + /// A channel source. + IChannelSourceHandle GetReadChannelSource(IReadOnlyCollection deprioritizedServers, CancellationToken cancellationToken); + + /// + /// Gets a channel source for read operations while deprioritizing servers in the provided collection. + /// + /// The deprioritized servers. + /// The cancellation token. + /// A channel source. + Task GetReadChannelSourceAsync(IReadOnlyCollection deprioritizedServers, CancellationToken cancellationToken); } /// @@ -75,6 +92,14 @@ public interface IWriteBinding : IBinding /// A channel source. IChannelSourceHandle GetWriteChannelSource(CancellationToken cancellationToken); + /// + /// Gets a channel source for write operations while deprioritizing servers in the provided collection. + /// + /// The deprioritized servers. + /// The cancellation token. + /// A channel source. + IChannelSourceHandle GetWriteChannelSource(IReadOnlyCollection deprioritizedServers, CancellationToken cancellationToken); + /// /// Gets a channel source for write operations that may use a secondary. /// @@ -83,6 +108,15 @@ public interface IWriteBinding : IBinding /// A channel source. IChannelSourceHandle GetWriteChannelSource(IMayUseSecondaryCriteria mayUseSecondary, CancellationToken cancellationToken); + /// + /// Gets a channel source for write operations that may use a secondary and deprioritizes servers in the provided collection. + /// + /// The deprioritized servers. + /// The may use secondary criteria. + /// The cancellation token. + /// A channel source. + IChannelSourceHandle GetWriteChannelSource(IReadOnlyCollection deprioritizedServers, IMayUseSecondaryCriteria mayUseSecondary, CancellationToken cancellationToken); + /// /// Gets a channel source for write operations. /// @@ -90,6 +124,14 @@ public interface IWriteBinding : IBinding /// A channel source. Task GetWriteChannelSourceAsync(CancellationToken cancellationToken); + /// + /// Gets a channel source for write operations while deprioritizing servers in the provided collection. + /// + /// The deprioritized servers. + /// The cancellation token. + /// A channel source. + Task GetWriteChannelSourceAsync(IReadOnlyCollection deprioritizedServers, CancellationToken cancellationToken); + /// /// Gets a channel source for write operations that may use a secondary. /// @@ -97,6 +139,15 @@ public interface IWriteBinding : IBinding /// The cancellation token. /// A channel source. Task GetWriteChannelSourceAsync(IMayUseSecondaryCriteria mayUseSecondary, CancellationToken cancellationToken); + + /// + /// Gets a channel source for write operations that may use a secondary and deprioritizes servers in the provided collection. + /// + /// The deprioritized servers. + /// The may use secondary criteria. + /// The cancellation token. + /// A channel source. + Task GetWriteChannelSourceAsync(IReadOnlyCollection deprioritizedServers, IMayUseSecondaryCriteria mayUseSecondary, CancellationToken cancellationToken); } /// diff --git a/src/MongoDB.Driver.Core/Core/Bindings/ReadBindingHandle.cs b/src/MongoDB.Driver.Core/Core/Bindings/ReadBindingHandle.cs index f190db358d0..6c8283d2bfd 100644 --- a/src/MongoDB.Driver.Core/Core/Bindings/ReadBindingHandle.cs +++ b/src/MongoDB.Driver.Core/Core/Bindings/ReadBindingHandle.cs @@ -15,12 +15,10 @@ using System; using System.Collections.Generic; -using System.Linq; -using System.Text; using System.Threading; using System.Threading.Tasks; -using MongoDB.Driver.Core.Clusters; using MongoDB.Driver.Core.Misc; +using MongoDB.Driver.Core.Servers; namespace MongoDB.Driver.Core.Bindings { @@ -76,6 +74,20 @@ public Task GetReadChannelSourceAsync(CancellationToken ca return _reference.Instance.GetReadChannelSourceAsync(cancellationToken); } + /// + public IChannelSourceHandle GetReadChannelSource(IReadOnlyCollection deprioritizedServers, CancellationToken cancellationToken) + { + ThrowIfDisposed(); + return _reference.Instance.GetReadChannelSource(deprioritizedServers, cancellationToken); + } + + /// + public Task GetReadChannelSourceAsync(IReadOnlyCollection deprioritizedServers, CancellationToken cancellationToken) + { + ThrowIfDisposed(); + return _reference.Instance.GetReadChannelSourceAsync(deprioritizedServers, cancellationToken); + } + /// public void Dispose() { diff --git a/src/MongoDB.Driver.Core/Core/Bindings/ReadPreferenceBinding.cs b/src/MongoDB.Driver.Core/Core/Bindings/ReadPreferenceBinding.cs index 5790a7e5be9..4bd662f53a7 100644 --- a/src/MongoDB.Driver.Core/Core/Bindings/ReadPreferenceBinding.cs +++ b/src/MongoDB.Driver.Core/Core/Bindings/ReadPreferenceBinding.cs @@ -14,6 +14,7 @@ */ using System; +using System.Collections.Generic; using System.Threading; using System.Threading.Tasks; using MongoDB.Driver.Core.Clusters; @@ -67,16 +68,28 @@ public ICoreSessionHandle Session /// public IChannelSourceHandle GetReadChannelSource(CancellationToken cancellationToken) { - ThrowIfDisposed(); - var server = _cluster.SelectServerAndPinIfNeeded(_session, _serverSelector, cancellationToken); - return GetChannelSourceHelper(server); + return GetReadChannelSource(null, cancellationToken); } /// public async Task GetReadChannelSourceAsync(CancellationToken cancellationToken) + { + return await GetReadChannelSourceAsync(null, cancellationToken).ConfigureAwait(false); + } + + /// + public IChannelSourceHandle GetReadChannelSource(IReadOnlyCollection deprioritizedServers, CancellationToken cancellationToken) + { + ThrowIfDisposed(); + var server = _cluster.SelectServerAndPinIfNeeded(_session, _serverSelector, deprioritizedServers, cancellationToken); + return GetChannelSourceHelper(server); + } + + /// + public async Task GetReadChannelSourceAsync(IReadOnlyCollection deprioritizedServers, CancellationToken cancellationToken) { ThrowIfDisposed(); - var server = await _cluster.SelectServerAndPinIfNeededAsync(_session, _serverSelector, cancellationToken).ConfigureAwait(false); + var server = await _cluster.SelectServerAndPinIfNeededAsync(_session, _serverSelector, deprioritizedServers, cancellationToken).ConfigureAwait(false); return GetChannelSourceHelper(server); } diff --git a/src/MongoDB.Driver.Core/Core/Bindings/ReadWriteBindingHandle.cs b/src/MongoDB.Driver.Core/Core/Bindings/ReadWriteBindingHandle.cs index c205eb33ade..205e47dfdf4 100644 --- a/src/MongoDB.Driver.Core/Core/Bindings/ReadWriteBindingHandle.cs +++ b/src/MongoDB.Driver.Core/Core/Bindings/ReadWriteBindingHandle.cs @@ -15,13 +15,10 @@ using System; using System.Collections.Generic; -using System.Linq; -using System.Text; using System.Threading; using System.Threading.Tasks; -using MongoDB.Driver.Core.Clusters; using MongoDB.Driver.Core.Misc; -using MongoDB.Driver.Core.Operations; +using MongoDB.Driver.Core.Servers; namespace MongoDB.Driver.Core.Bindings { @@ -77,6 +74,20 @@ public Task GetReadChannelSourceAsync(CancellationToken ca return _reference.Instance.GetReadChannelSourceAsync(cancellationToken); } + /// + public IChannelSourceHandle GetReadChannelSource(IReadOnlyCollection deprioritizedServers, CancellationToken cancellationToken) + { + ThrowIfDisposed(); + return _reference.Instance.GetReadChannelSource(deprioritizedServers, cancellationToken); + } + + /// + public Task GetReadChannelSourceAsync(IReadOnlyCollection deprioritizedServers, CancellationToken cancellationToken) + { + ThrowIfDisposed(); + return _reference.Instance.GetReadChannelSourceAsync(deprioritizedServers, cancellationToken); + } + /// public IChannelSourceHandle GetWriteChannelSource(CancellationToken cancellationToken) { @@ -84,6 +95,13 @@ public IChannelSourceHandle GetWriteChannelSource(CancellationToken cancellation return _reference.Instance.GetWriteChannelSource(cancellationToken); } + /// + public IChannelSourceHandle GetWriteChannelSource(IReadOnlyCollection deprioritizedServers, CancellationToken cancellationToken) + { + ThrowIfDisposed(); + return _reference.Instance.GetWriteChannelSource(deprioritizedServers, cancellationToken); + } + /// public IChannelSourceHandle GetWriteChannelSource(IMayUseSecondaryCriteria mayUseSecondary, CancellationToken cancellationToken) { @@ -91,6 +109,13 @@ public IChannelSourceHandle GetWriteChannelSource(IMayUseSecondaryCriteria mayUs return _reference.Instance.GetWriteChannelSource(mayUseSecondary, cancellationToken); } + /// + public IChannelSourceHandle GetWriteChannelSource(IReadOnlyCollection deprioritizedServers, IMayUseSecondaryCriteria mayUseSecondary, CancellationToken cancellationToken) + { + ThrowIfDisposed(); + return _reference.Instance.GetWriteChannelSource(deprioritizedServers, mayUseSecondary, cancellationToken); + } + /// public Task GetWriteChannelSourceAsync(CancellationToken cancellationToken) { @@ -98,6 +123,13 @@ public Task GetWriteChannelSourceAsync(CancellationToken c return _reference.Instance.GetWriteChannelSourceAsync(cancellationToken); } + /// + public Task GetWriteChannelSourceAsync(IReadOnlyCollection deprioritizedServers, CancellationToken cancellationToken) + { + ThrowIfDisposed(); + return _reference.Instance.GetWriteChannelSourceAsync(deprioritizedServers, cancellationToken); + } + /// public Task GetWriteChannelSourceAsync(IMayUseSecondaryCriteria mayUseSecondary, CancellationToken cancellationToken) { @@ -105,6 +137,13 @@ public Task GetWriteChannelSourceAsync(IMayUseSecondaryCri return _reference.Instance.GetWriteChannelSourceAsync(mayUseSecondary, cancellationToken); } + /// + public Task GetWriteChannelSourceAsync(IReadOnlyCollection deprioritizedServers, IMayUseSecondaryCriteria mayUseSecondary, CancellationToken cancellationToken) + { + ThrowIfDisposed(); + return _reference.Instance.GetWriteChannelSourceAsync(deprioritizedServers, mayUseSecondary, cancellationToken); + } + /// public void Dispose() { diff --git a/src/MongoDB.Driver.Core/Core/Bindings/SingleServerReadBinding.cs b/src/MongoDB.Driver.Core/Core/Bindings/SingleServerReadBinding.cs index 4415c65d325..7666ef3e719 100644 --- a/src/MongoDB.Driver.Core/Core/Bindings/SingleServerReadBinding.cs +++ b/src/MongoDB.Driver.Core/Core/Bindings/SingleServerReadBinding.cs @@ -14,6 +14,7 @@ */ using System; +using System.Collections.Generic; using System.Threading; using System.Threading.Tasks; using MongoDB.Driver.Core.Misc; @@ -77,6 +78,18 @@ public Task GetReadChannelSourceAsync(CancellationToken ca return Task.FromResult(GetChannelSourceHelper()); } + /// + public IChannelSourceHandle GetReadChannelSource(IReadOnlyCollection deprioritizedServers, CancellationToken cancellationToken) + { + return GetReadChannelSource(cancellationToken); + } + + /// + public Task GetReadChannelSourceAsync(IReadOnlyCollection deprioritizedServers, CancellationToken cancellationToken) + { + return GetReadChannelSourceAsync(cancellationToken); + } + /// public void Dispose() { diff --git a/src/MongoDB.Driver.Core/Core/Bindings/SingleServerReadWriteBinding.cs b/src/MongoDB.Driver.Core/Core/Bindings/SingleServerReadWriteBinding.cs index 09acb647105..8fec85d3249 100644 --- a/src/MongoDB.Driver.Core/Core/Bindings/SingleServerReadWriteBinding.cs +++ b/src/MongoDB.Driver.Core/Core/Bindings/SingleServerReadWriteBinding.cs @@ -14,6 +14,7 @@ */ using System; +using System.Collections.Generic; using System.Threading; using System.Threading.Tasks; using MongoDB.Driver.Core.Misc; @@ -81,6 +82,18 @@ public Task GetReadChannelSourceAsync(CancellationToken ca return Task.FromResult(GetChannelSourceHelper()); } + /// + public IChannelSourceHandle GetReadChannelSource(IReadOnlyCollection deprioritizedServers, CancellationToken cancellationToken) + { + return GetReadChannelSource(cancellationToken); + } + + /// + public Task GetReadChannelSourceAsync(IReadOnlyCollection deprioritizedServers, CancellationToken cancellationToken) + { + return GetReadChannelSourceAsync(cancellationToken); + } + /// public IChannelSourceHandle GetWriteChannelSource(CancellationToken cancellationToken) { @@ -88,12 +101,24 @@ public IChannelSourceHandle GetWriteChannelSource(CancellationToken cancellation return GetChannelSourceHelper(); } + /// + public IChannelSourceHandle GetWriteChannelSource(IReadOnlyCollection deprioritizedServers, CancellationToken cancellationToken) + { + return GetWriteChannelSource(cancellationToken); + } + /// public IChannelSourceHandle GetWriteChannelSource(IMayUseSecondaryCriteria mayUseSecondary, CancellationToken cancellationToken) { return GetWriteChannelSource(cancellationToken); // ignore mayUseSecondary } + /// + public IChannelSourceHandle GetWriteChannelSource(IReadOnlyCollection deprioritizedServers, IMayUseSecondaryCriteria mayUseSecondary, CancellationToken cancellationToken) + { + return GetWriteChannelSource(mayUseSecondary, cancellationToken); + } + /// public Task GetWriteChannelSourceAsync(CancellationToken cancellationToken) { @@ -101,12 +126,24 @@ public Task GetWriteChannelSourceAsync(CancellationToken c return Task.FromResult(GetChannelSourceHelper()); } + /// + public Task GetWriteChannelSourceAsync(IReadOnlyCollection deprioritizedServers, CancellationToken cancellationToken) + { + return GetWriteChannelSourceAsync(cancellationToken); + } + /// public Task GetWriteChannelSourceAsync(IMayUseSecondaryCriteria mayUseSecondary, CancellationToken cancellationToken) { return GetWriteChannelSourceAsync(cancellationToken); // ignore mayUseSecondary } + /// + public Task GetWriteChannelSourceAsync(IReadOnlyCollection deprioritizedServers, IMayUseSecondaryCriteria mayUseSecondary, CancellationToken cancellationToken) + { + return GetWriteChannelSourceAsync(mayUseSecondary, cancellationToken); + } + private IChannelSourceHandle GetChannelSourceHelper() { return new ChannelSourceHandle(new ServerChannelSource(_server, _session.Fork())); diff --git a/src/MongoDB.Driver.Core/Core/Bindings/WritableServerBinding.cs b/src/MongoDB.Driver.Core/Core/Bindings/WritableServerBinding.cs index 8bb61bb5563..379adc02944 100644 --- a/src/MongoDB.Driver.Core/Core/Bindings/WritableServerBinding.cs +++ b/src/MongoDB.Driver.Core/Core/Bindings/WritableServerBinding.cs @@ -14,6 +14,7 @@ */ using System; +using System.Collections.Generic; using System.Threading; using System.Threading.Tasks; using MongoDB.Driver.Core.Clusters; @@ -62,30 +63,53 @@ public ICoreSessionHandle Session /// public IChannelSourceHandle GetReadChannelSource(CancellationToken cancellationToken) { - ThrowIfDisposed(); - var server = _cluster.SelectServerAndPinIfNeeded(_session, WritableServerSelector.Instance, cancellationToken); - - return CreateServerChannelSource(server); + return GetReadChannelSource(null, cancellationToken); } /// public async Task GetReadChannelSourceAsync(CancellationToken cancellationToken) + { + return await GetReadChannelSourceAsync(null, cancellationToken).ConfigureAwait(false); + } + + /// + public IChannelSourceHandle GetReadChannelSource(IReadOnlyCollection deprioritizedServers, CancellationToken cancellationToken) { ThrowIfDisposed(); - var server = await _cluster.SelectServerAndPinIfNeededAsync(_session, WritableServerSelector.Instance, cancellationToken).ConfigureAwait(false); + var server = _cluster.SelectServerAndPinIfNeeded(_session, WritableServerSelector.Instance, deprioritizedServers, cancellationToken); + return CreateServerChannelSource(server); + } + + /// + public async Task GetReadChannelSourceAsync(IReadOnlyCollection deprioritizedServers, CancellationToken cancellationToken) + { + ThrowIfDisposed(); + var server = await _cluster.SelectServerAndPinIfNeededAsync(_session, WritableServerSelector.Instance, deprioritizedServers, cancellationToken).ConfigureAwait(false); return CreateServerChannelSource(server); } /// public IChannelSourceHandle GetWriteChannelSource(CancellationToken cancellationToken) + { + return GetWriteChannelSource(deprioritizedServers: null, cancellationToken); + } + + /// + public IChannelSourceHandle GetWriteChannelSource(IReadOnlyCollection deprioritizedServers, CancellationToken cancellationToken) { ThrowIfDisposed(); - var server = _cluster.SelectServerAndPinIfNeeded(_session, WritableServerSelector.Instance, cancellationToken); + var server = _cluster.SelectServerAndPinIfNeeded(_session, WritableServerSelector.Instance, deprioritizedServers, cancellationToken); return CreateServerChannelSource(server); } /// public IChannelSourceHandle GetWriteChannelSource(IMayUseSecondaryCriteria mayUseSecondary, CancellationToken cancellationToken) + { + return GetWriteChannelSource(null, mayUseSecondary, cancellationToken); + } + + /// + public IChannelSourceHandle GetWriteChannelSource(IReadOnlyCollection deprioritizedServers, IMayUseSecondaryCriteria mayUseSecondary, CancellationToken cancellationToken) { if (IsSessionPinnedToServer()) { @@ -93,20 +117,32 @@ public IChannelSourceHandle GetWriteChannelSource(IMayUseSecondaryCriteria mayUs } var selector = new WritableServerSelector(mayUseSecondary); - var server = _cluster.SelectServer(selector, cancellationToken); + var server = _cluster.SelectServer(selector, deprioritizedServers, cancellationToken); return CreateServerChannelSource(server); } /// public async Task GetWriteChannelSourceAsync(CancellationToken cancellationToken) + { + return await GetWriteChannelSourceAsync(deprioritizedServers: null, cancellationToken).ConfigureAwait(false); + } + + /// + public async Task GetWriteChannelSourceAsync(IReadOnlyCollection deprioritizedServers, CancellationToken cancellationToken) { ThrowIfDisposed(); - var server = await _cluster.SelectServerAndPinIfNeededAsync(_session, WritableServerSelector.Instance, cancellationToken).ConfigureAwait(false); + var server = await _cluster.SelectServerAndPinIfNeededAsync(_session, WritableServerSelector.Instance, deprioritizedServers, cancellationToken).ConfigureAwait(false); return CreateServerChannelSource(server); } /// public async Task GetWriteChannelSourceAsync(IMayUseSecondaryCriteria mayUseSecondary, CancellationToken cancellationToken) + { + return await GetWriteChannelSourceAsync(null, mayUseSecondary, cancellationToken).ConfigureAwait(false); + } + + /// + public async Task GetWriteChannelSourceAsync(IReadOnlyCollection deprioritizedServers, IMayUseSecondaryCriteria mayUseSecondary, CancellationToken cancellationToken) { if (IsSessionPinnedToServer()) { @@ -114,7 +150,7 @@ public async Task GetWriteChannelSourceAsync(IMayUseSecond } var selector = new WritableServerSelector(mayUseSecondary); - var server = await _cluster.SelectServerAsync(selector, cancellationToken).ConfigureAwait(false); + var server = await _cluster.SelectServerAsync(selector, deprioritizedServers, cancellationToken).ConfigureAwait(false); return CreateServerChannelSource(server); } diff --git a/src/MongoDB.Driver.Core/Core/Clusters/IClusterExtensions.cs b/src/MongoDB.Driver.Core/Core/Clusters/IClusterExtensions.cs index e5cabd39243..fea76186a7c 100644 --- a/src/MongoDB.Driver.Core/Core/Clusters/IClusterExtensions.cs +++ b/src/MongoDB.Driver.Core/Core/Clusters/IClusterExtensions.cs @@ -13,6 +13,7 @@ * limitations under the License. */ +using System.Collections.Generic; using System.Threading; using System.Threading.Tasks; using MongoDB.Driver.Core.Bindings; @@ -30,6 +31,7 @@ public static IServer SelectServerAndPinIfNeeded( this ICluster cluster, ICoreSessionHandle session, IServerSelector selector, + IReadOnlyCollection deprioritizedServers, CancellationToken cancellationToken) { var pinnedServer = GetPinnedServerIfValid(cluster, session); @@ -40,7 +42,7 @@ public static IServer SelectServerAndPinIfNeeded( // Server selection also updates the cluster type, allowing us to to determine if the server // should be pinned. - var server = cluster.SelectServer(selector, cancellationToken); + var server = cluster.SelectServer(selector, deprioritizedServers, cancellationToken); PinServerIfNeeded(cluster, session, server); return server; } @@ -49,6 +51,7 @@ public static async Task SelectServerAndPinIfNeededAsync( this ICluster cluster, ICoreSessionHandle session, IServerSelector selector, + IReadOnlyCollection deprioritizedServers, CancellationToken cancellationToken) { var pinnedServer = GetPinnedServerIfValid(cluster, session); @@ -59,7 +62,7 @@ public static async Task SelectServerAndPinIfNeededAsync( // Server selection also updates the cluster type, allowing us to to determine if the server // should be pinned. - var server = await cluster.SelectServerAsync(selector, cancellationToken).ConfigureAwait(false); + var server = await cluster.SelectServerAsync(selector, deprioritizedServers, cancellationToken).ConfigureAwait(false); PinServerIfNeeded(cluster, session, server); return server; diff --git a/src/MongoDB.Driver.Core/Core/Operations/RetryableReadOperationExecutor.cs b/src/MongoDB.Driver.Core/Core/Operations/RetryableReadOperationExecutor.cs index d17cc437ab3..cebcdf594a1 100644 --- a/src/MongoDB.Driver.Core/Core/Operations/RetryableReadOperationExecutor.cs +++ b/src/MongoDB.Driver.Core/Core/Operations/RetryableReadOperationExecutor.cs @@ -51,7 +51,7 @@ public static TResult Execute(IRetryableReadOperation operatio try { - context.ReplaceChannelSource(context.Binding.GetReadChannelSource(cancellationToken)); + context.ReplaceChannelSource(context.Binding.GetReadChannelSource(new []{ context.ChannelSource.ServerDescription }, cancellationToken)); context.ReplaceChannel(context.ChannelSource.GetChannel(cancellationToken)); } catch @@ -96,7 +96,7 @@ public static async Task ExecuteAsync(IRetryableReadOperation< try { - context.ReplaceChannelSource(context.Binding.GetReadChannelSource(cancellationToken)); + context.ReplaceChannelSource(context.Binding.GetReadChannelSource(new []{ context.ChannelSource.ServerDescription }, cancellationToken)); context.ReplaceChannel(context.ChannelSource.GetChannel(cancellationToken)); } catch diff --git a/src/MongoDB.Driver.Core/Core/Operations/RetryableWriteOperationExecutor.cs b/src/MongoDB.Driver.Core/Core/Operations/RetryableWriteOperationExecutor.cs index 86087929ae7..edb59aec00a 100644 --- a/src/MongoDB.Driver.Core/Core/Operations/RetryableWriteOperationExecutor.cs +++ b/src/MongoDB.Driver.Core/Core/Operations/RetryableWriteOperationExecutor.cs @@ -53,7 +53,7 @@ public static TResult Execute(IRetryableWriteOperation operati try { - context.ReplaceChannelSource(context.Binding.GetWriteChannelSource(cancellationToken)); + context.ReplaceChannelSource(context.Binding.GetWriteChannelSource(new []{ context.ChannelSource.ServerDescription }, cancellationToken)); context.ReplaceChannel(context.ChannelSource.GetChannel(cancellationToken)); } catch @@ -104,7 +104,7 @@ public static async Task ExecuteAsync(IRetryableWriteOperation try { - context.ReplaceChannelSource(await context.Binding.GetWriteChannelSourceAsync(cancellationToken).ConfigureAwait(false)); + context.ReplaceChannelSource(await context.Binding.GetWriteChannelSourceAsync(new []{ context.ChannelSource.ServerDescription }, cancellationToken).ConfigureAwait(false)); context.ReplaceChannel(await context.ChannelSource.GetChannelAsync(cancellationToken).ConfigureAwait(false)); } catch diff --git a/tests/MongoDB.Driver.Core.Tests/Core/Bindings/CoreServerSessionPoolTests.cs b/tests/MongoDB.Driver.Core.Tests/Core/Bindings/CoreServerSessionPoolTests.cs index 930eb24a2af..0996d933304 100644 --- a/tests/MongoDB.Driver.Core.Tests/Core/Bindings/CoreServerSessionPoolTests.cs +++ b/tests/MongoDB.Driver.Core.Tests/Core/Bindings/CoreServerSessionPoolTests.cs @@ -309,6 +309,8 @@ public TestCluster(ClusterType clusterType) public void Initialize() => DescriptionChanged?.Invoke(this, new ClusterDescriptionChangedEventArgs(Description, Description)); public IServer SelectServer(IServerSelector selector, CancellationToken cancellationToken) => throw new NotImplementedException(); public Task SelectServerAsync(IServerSelector selector, CancellationToken cancellationToken) => throw new NotImplementedException(); + public IServer SelectServer(IServerSelector selector, IReadOnlyCollection deprioritizedServers, CancellationToken cancellationToken) => throw new NotImplementedException(); + public Task SelectServerAsync(IServerSelector selector, IReadOnlyCollection deprioritizedServers, CancellationToken cancellationToken) => throw new NotImplementedException(); public ICoreSessionHandle StartSession(CoreSessionOptions options = null) => throw new NotImplementedException(); } } From 464b4981f8b68ad986b5156c966acfeae811582c Mon Sep 17 00:00:00 2001 From: adelinowona Date: Wed, 3 Apr 2024 15:42:57 -0400 Subject: [PATCH 04/24] add new prose tests --- .../RetryableReadsProseTests.cs | 127 +++++++++++++- .../prose-tests/RetryWriteOnOtherMongos.cs | 155 ++++++++++++++++++ 2 files changed, 279 insertions(+), 3 deletions(-) create mode 100644 tests/MongoDB.Driver.Tests/Specifications/retryable-writes/prose-tests/RetryWriteOnOtherMongos.cs diff --git a/tests/MongoDB.Driver.Tests/Specifications/retryable-reads/RetryableReadsProseTests.cs b/tests/MongoDB.Driver.Tests/Specifications/retryable-reads/RetryableReadsProseTests.cs index 79f34dbafca..9d6eeebaa06 100644 --- a/tests/MongoDB.Driver.Tests/Specifications/retryable-reads/RetryableReadsProseTests.cs +++ b/tests/MongoDB.Driver.Tests/Specifications/retryable-reads/RetryableReadsProseTests.cs @@ -20,21 +20,29 @@ using FluentAssertions; using MongoDB.Bson; using MongoDB.Bson.TestHelpers; -using MongoDB.TestHelpers.XunitExtensions; using MongoDB.Driver.Core; using MongoDB.Driver.Core.Bindings; +using MongoDB.Driver.Core.Clusters; using MongoDB.Driver.Core.Clusters.ServerSelectors; using MongoDB.Driver.Core.Events; using MongoDB.Driver.Core.Misc; using MongoDB.Driver.Core.TestHelpers; +using MongoDB.Driver.Core.TestHelpers.Logging; using MongoDB.Driver.Core.TestHelpers.XunitExtensions; using MongoDB.Driver.TestHelpers; +using MongoDB.Driver.Tests.Specifications.connection_monitoring_and_pooling; +using MongoDB.TestHelpers.XunitExtensions; using Xunit; +using Xunit.Abstractions; namespace MongoDB.Driver.Tests.Specifications.retryable_reads { - public class RetryableReadsProseTests + public class RetryableReadsProseTests : LoggableTestClass { + public RetryableReadsProseTests(ITestOutputHelper output) : base(output, includeAllCategories: true) + { + } + [Theory] [ParameterAttributeData] public async Task PoolClearedError_read_retryablity_test([Values(true, false)] bool async) @@ -60,7 +68,7 @@ public async Task PoolClearedError_read_retryablity_test([Values(true, false)] b IServerSelector failPointSelector = new ReadPreferenceServerSelector(ReadPreference.Primary); var settings = DriverTestConfiguration.GetClientSettings(); - if (CoreTestConfiguration.Cluster.Description.Type == Core.Clusters.ClusterType.Sharded) + if (CoreTestConfiguration.Cluster.Description.Type == ClusterType.Sharded) { var serverAddress = settings.Servers.First(); settings.Servers = new[] { serverAddress }; @@ -120,6 +128,119 @@ await ThreadingUtilities.ExecuteTasksOnNewThreads(2, async __ => eventCapturer.Events.OfType().Count().Should().Be(1); } + [Fact] + public void Sharded_cluster_retryable_reads_are_retried_on_different_mongos_if_available() + { + RequireServer.Check() + .Supports(Feature.FailPointsFailCommandForSharded) + .ClusterTypes(ClusterType.Sharded) + .MultipleMongoses(true); + + var failPointCommand = BsonDocument.Parse( + @"{ + configureFailPoint: ""failCommand"", + mode: { times: 1 }, + data: + { + failCommands: [""find""], + errorCode: 6 + } + }"); + + var eventCapturer = new EventCapturer() + .Capture(); + + using var client = DriverTestConfiguration.CreateDisposableClient( + s => + { + s.RetryReads = true; + s.ClusterConfigurator = b => b.Subscribe(eventCapturer); + } + , LoggingSettings, true); + + var failPointServer1 = client.Cluster.SelectServer(new EndPointServerSelector(client.Cluster.Description.Servers[0].EndPoint), default); + var failPointServer2 = client.Cluster.SelectServer(new EndPointServerSelector(client.Cluster.Description.Servers[1].EndPoint), default); + + using var failPoint1 = FailPoint.Configure(failPointServer1, NoCoreSession.NewHandle(), failPointCommand); + using var failPoint2 = FailPoint.Configure(failPointServer2, NoCoreSession.NewHandle(), failPointCommand); + + var database = client.GetDatabase(DriverTestConfiguration.DatabaseNamespace.DatabaseName); + var collection = database.GetCollection(DriverTestConfiguration.CollectionNamespace.CollectionName); + + Assert.Throws(() => + { + collection.Find(Builders.Filter.Empty).ToList(); + }); + + eventCapturer.Events.OfType().Count().Should().Be(2); + + var event1 = eventCapturer.Events[0].As(); + var event2 = eventCapturer.Events[1].As(); + event1.CommandName.Should().Be(event2.CommandName).And.Be("find"); + event1.ConnectionId.ServerId().Should().NotBe(event2.ConnectionId.ServerId()); + + // Assert the deprioritization debug message was emitted for deprioritized server. + Logs.Count(log => log.Category == "MongoDB.ServerSelection" && log.Message.StartsWith("Deprioritization")).Should().Be(1); + } + + [Fact] + public void Sharded_cluster_retryable_reads_are_retried_on_same_mongo_if_no_other_is_available() + { + RequireServer.Check() + .Supports(Feature.FailPointsFailCommandForSharded) + .ClusterTypes(ClusterType.Sharded); + + var failPointCommand = BsonDocument.Parse( + @"{ + configureFailPoint: ""failCommand"", + mode: { times: 1 }, + data: + { + failCommands: [""find""], + errorCode: 6 + } + }"); + + var eventCapturer = new EventCapturer() + .Capture() + .Capture(); + + using var client = DriverTestConfiguration.CreateDisposableClient( + s => + { + s.RetryReads = true; + s.DirectConnection = false; + s.ClusterConfigurator = b => b.Subscribe(eventCapturer); + } + , LoggingSettings, true); + + var failPointServer = client.Cluster.SelectServer(new EndPointServerSelector(client.Cluster.Description.Servers[0].EndPoint), default); + + using var failPoint = FailPoint.Configure(failPointServer, NoCoreSession.NewHandle(), failPointCommand); + + var database = client.GetDatabase(DriverTestConfiguration.DatabaseNamespace.DatabaseName); + var collection = database.GetCollection(DriverTestConfiguration.CollectionNamespace.CollectionName); + + // clear command succeeded events captured from initial hello + eventCapturer.Clear(); + + collection.Find(Builders.Filter.Empty).ToList(); + + eventCapturer.Events.Count.Should().Be(2); + eventCapturer.Events.OfType().Count().Should().Be(1); + eventCapturer.Events.OfType().Count().Should().Be(1); + + var event1 = eventCapturer.Events[0].As(); + var event2 = eventCapturer.Events[1].As(); + event1.CommandName.Should().Be(event2.CommandName).And.Be("find"); + event1.ConnectionId.ServerId().Should().Be(event2.ConnectionId.ServerId()); + + // Assert the deprioritization debug messages were emitted + // one for deprioritizing the failpointServer and another for + // reverting the deprioritization since we have no other suitable servers in this test + Logs.Count(log => log.Category == "MongoDB.ServerSelection" && log.Message.StartsWith("Deprioritization")).Should().Be(2); + } + // private methods private DisposableMongoClient CreateClient(MongoClientSettings mongoClientSettings, EventCapturer eventCapturer, TimeSpan heartbeatInterval, string applicationName = null) { diff --git a/tests/MongoDB.Driver.Tests/Specifications/retryable-writes/prose-tests/RetryWriteOnOtherMongos.cs b/tests/MongoDB.Driver.Tests/Specifications/retryable-writes/prose-tests/RetryWriteOnOtherMongos.cs new file mode 100644 index 00000000000..e0dd24f5232 --- /dev/null +++ b/tests/MongoDB.Driver.Tests/Specifications/retryable-writes/prose-tests/RetryWriteOnOtherMongos.cs @@ -0,0 +1,155 @@ +/* Copyright 2021-present MongoDB Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +using System.Linq; +using FluentAssertions; +using MongoDB.Bson; +using MongoDB.Driver.Core; +using MongoDB.Driver.Core.Bindings; +using MongoDB.Driver.Core.Clusters; +using MongoDB.Driver.Core.Clusters.ServerSelectors; +using MongoDB.Driver.Core.Events; +using MongoDB.Driver.Core.Misc; +using MongoDB.Driver.Core.TestHelpers; +using MongoDB.Driver.Core.TestHelpers.Logging; +using MongoDB.Driver.Core.TestHelpers.XunitExtensions; +using MongoDB.Driver.Tests.Specifications.connection_monitoring_and_pooling; +using Xunit; +using Xunit.Abstractions; + +namespace MongoDB.Driver.Tests.Specifications.retryable_writes.prose_tests +{ + public class RetryWriteOnOtherMongos : LoggableTestClass + { + public RetryWriteOnOtherMongos(ITestOutputHelper output) : base(output, includeAllCategories: true) + { + } + + [Fact] + public void Sharded_cluster_retryable_writes_are_retried_on_different_mongos_if_available() + { + RequireServer.Check() + .Supports(Feature.FailPointsFailCommandForSharded) + .ClusterTypes(ClusterType.Sharded) + .MultipleMongoses(true); + + var failPointCommand = BsonDocument.Parse( + @"{ + configureFailPoint: ""failCommand"", + mode: { times: 1 }, + data: + { + failCommands: [""insert""], + errorCode: 6, + errorLabels: [""RetryableWriteError""] + } + }"); + + var eventCapturer = new EventCapturer() + .Capture(); + + using var client = DriverTestConfiguration.CreateDisposableClient( + s => + { + s.RetryWrites = true; + s.ClusterConfigurator = b => b.Subscribe(eventCapturer); + } + , LoggingSettings, true); + + var failPointServer1 = client.Cluster.SelectServer(new EndPointServerSelector(client.Cluster.Description.Servers[0].EndPoint), default); + var failPointServer2 = client.Cluster.SelectServer(new EndPointServerSelector(client.Cluster.Description.Servers[1].EndPoint), default); + + using var failPoint1 = FailPoint.Configure(failPointServer1, NoCoreSession.NewHandle(), failPointCommand); + using var failPoint2 = FailPoint.Configure(failPointServer2, NoCoreSession.NewHandle(), failPointCommand); + + var database = client.GetDatabase(DriverTestConfiguration.DatabaseNamespace.DatabaseName); + var collection = database.GetCollection(DriverTestConfiguration.CollectionNamespace.CollectionName); + + Assert.Throws(() => + { + collection.InsertOne(new BsonDocument("x", 1)); + }); + + eventCapturer.Events.OfType().Count().Should().Be(2); + + var event1 = eventCapturer.Events[0].As(); + var event2 = eventCapturer.Events[1].As(); + event1.CommandName.Should().Be(event2.CommandName).And.Be("insert"); + event1.ConnectionId.ServerId().Should().NotBe(event2.ConnectionId.ServerId()); + + // Assert the deprioritization debug message was emitted for deprioritized server. + Logs.Count(log => log.Category == "MongoDB.ServerSelection" && log.Message.StartsWith("Deprioritization")).Should().Be(1); + } + + [Fact] + public void Sharded_cluster_retryable_writes_are_retried_on_same_mongo_if_no_other_is_available() + { + RequireServer.Check() + .Supports(Feature.FailPointsFailCommandForSharded) + .ClusterTypes(ClusterType.Sharded); + + var failPointCommand = BsonDocument.Parse( + @"{ + configureFailPoint: ""failCommand"", + mode: { times: 1 }, + data: + { + failCommands: [""insert""], + errorCode: 6, + errorLabels: [""RetryableWriteError""] + } + }"); + + var eventCapturer = new EventCapturer() + .Capture() + .Capture(); + + using var client = DriverTestConfiguration.CreateDisposableClient( + s => + { + s.RetryWrites = true; + s.DirectConnection = false; + s.ClusterConfigurator = b => b.Subscribe(eventCapturer); + } + , LoggingSettings, true); + + var failPointServer = client.Cluster.SelectServer(new EndPointServerSelector(client.Cluster.Description.Servers[0].EndPoint), default); + + using var failPoint = FailPoint.Configure(failPointServer, NoCoreSession.NewHandle(), failPointCommand); + + var database = client.GetDatabase(DriverTestConfiguration.DatabaseNamespace.DatabaseName); + var collection = database.GetCollection(DriverTestConfiguration.CollectionNamespace.CollectionName); + + // clear command succeeded events captured from initial hello + eventCapturer.Clear(); + + collection.InsertOne(new BsonDocument("x", 1)); + + eventCapturer.Events.Count.Should().Be(2); + eventCapturer.Events.OfType().Count().Should().Be(1); + eventCapturer.Events.OfType().Count().Should().Be(1); + + var event1 = eventCapturer.Events[0].As(); + var event2 = eventCapturer.Events[1].As(); + event1.CommandName.Should().Be(event2.CommandName).And.Be("insert"); + event1.ConnectionId.ServerId().Should().Be(event2.ConnectionId.ServerId()); + + // Assert the deprioritization debug messages were emitted + // one for deprioritizing the failpointServer and another for + // reverting the deprioritization since we have no other suitable servers in this test + Logs.Count(log => log.Category == "MongoDB.ServerSelection" && log.Message.StartsWith("Deprioritization")).Should().Be(2); + } + } +} From 5efce808053da3f784ededabde4e6f5dcc0d6361 Mon Sep 17 00:00:00 2001 From: adelinowona Date: Thu, 11 Apr 2024 13:13:08 -0400 Subject: [PATCH 05/24] Fix failing evergreen tests --- .../Bindings/ReadPreferenceBindingTests.cs | 12 +++++----- .../Bindings/WritableServerBindingTests.cs | 24 +++++++++---------- .../Core/Clusters/ClusterTests.cs | 4 ++++ .../Encryption/ClientEncryptionTests.cs | 8 +++---- 4 files changed, 26 insertions(+), 22 deletions(-) diff --git a/tests/MongoDB.Driver.Core.Tests/Core/Bindings/ReadPreferenceBindingTests.cs b/tests/MongoDB.Driver.Core.Tests/Core/Bindings/ReadPreferenceBindingTests.cs index 6f6468e5dbc..b523b942c83 100644 --- a/tests/MongoDB.Driver.Core.Tests/Core/Bindings/ReadPreferenceBindingTests.cs +++ b/tests/MongoDB.Driver.Core.Tests/Core/Bindings/ReadPreferenceBindingTests.cs @@ -119,19 +119,19 @@ public void GetReadChannelSource_should_use_a_read_preference_server_selector_to if (async) { - _mockCluster.Setup(c => c.SelectServerAsync(It.IsAny(), CancellationToken.None)).Returns(Task.FromResult(selectedServer)); + _mockCluster.Setup(c => c.SelectServerAsync(It.IsAny(), null, CancellationToken.None)).Returns(Task.FromResult(selectedServer)); subject.GetReadChannelSourceAsync(CancellationToken.None).GetAwaiter().GetResult(); - _mockCluster.Verify(c => c.SelectServerAsync(It.IsAny(), CancellationToken.None), Times.Once); + _mockCluster.Verify(c => c.SelectServerAsync(It.IsAny(), null, CancellationToken.None), Times.Once); } else { - _mockCluster.Setup(c => c.SelectServer(It.IsAny(), CancellationToken.None)).Returns(selectedServer); + _mockCluster.Setup(c => c.SelectServer(It.IsAny(), null, CancellationToken.None)).Returns(selectedServer); subject.GetReadChannelSource(CancellationToken.None); - _mockCluster.Verify(c => c.SelectServer(It.IsAny(), CancellationToken.None), Times.Once); + _mockCluster.Verify(c => c.SelectServer(It.IsAny(), null, CancellationToken.None), Times.Once); } } @@ -146,8 +146,8 @@ public void GetReadChannelSource_should_fork_the_session( var cancellationToken = cancellationTokenSource.Token; var selectedServer = new Mock().Object; - _mockCluster.Setup(m => m.SelectServer(It.IsAny(), cancellationToken)).Returns(selectedServer); - _mockCluster.Setup(m => m.SelectServerAsync(It.IsAny(), cancellationToken)).Returns(Task.FromResult(selectedServer)); + _mockCluster.Setup(m => m.SelectServer(It.IsAny(), null, cancellationToken)).Returns(selectedServer); + _mockCluster.Setup(m => m.SelectServerAsync(It.IsAny(), null, cancellationToken)).Returns(Task.FromResult(selectedServer)); var forkedSession = new Mock().Object; mockSession.Setup(m => m.Fork()).Returns(forkedSession); diff --git a/tests/MongoDB.Driver.Core.Tests/Core/Bindings/WritableServerBindingTests.cs b/tests/MongoDB.Driver.Core.Tests/Core/Bindings/WritableServerBindingTests.cs index 9ee482c2f6a..c71e283091b 100644 --- a/tests/MongoDB.Driver.Core.Tests/Core/Bindings/WritableServerBindingTests.cs +++ b/tests/MongoDB.Driver.Core.Tests/Core/Bindings/WritableServerBindingTests.cs @@ -123,19 +123,19 @@ public void GetReadChannelSource_should_use_a_writable_server_selector_to_select if (async) { - _mockCluster.Setup(c => c.SelectServerAsync(It.IsAny(), CancellationToken.None)).Returns(Task.FromResult(selectedServer)); + _mockCluster.Setup(c => c.SelectServerAsync(It.IsAny(), null, CancellationToken.None)).Returns(Task.FromResult(selectedServer)); subject.GetReadChannelSourceAsync(CancellationToken.None).GetAwaiter().GetResult(); - _mockCluster.Verify(c => c.SelectServerAsync(It.IsAny(), CancellationToken.None), Times.Once); + _mockCluster.Verify(c => c.SelectServerAsync(It.IsAny(), null, CancellationToken.None), Times.Once); } else { - _mockCluster.Setup(c => c.SelectServer(It.IsAny(), CancellationToken.None)).Returns(selectedServer); + _mockCluster.Setup(c => c.SelectServer(It.IsAny(), null, CancellationToken.None)).Returns(selectedServer); subject.GetReadChannelSource(CancellationToken.None); - _mockCluster.Verify(c => c.SelectServer(It.IsAny(), CancellationToken.None), Times.Once); + _mockCluster.Verify(c => c.SelectServer(It.IsAny(), null, CancellationToken.None), Times.Once); } } @@ -184,19 +184,19 @@ public void GetWriteChannelSourceAsync_should_use_a_writable_server_selector_to_ if (async) { - _mockCluster.Setup(c => c.SelectServerAsync(It.IsAny(), CancellationToken.None)).Returns(Task.FromResult(selectedServer)); + _mockCluster.Setup(c => c.SelectServerAsync(It.IsAny(), null, CancellationToken.None)).Returns(Task.FromResult(selectedServer)); subject.GetWriteChannelSourceAsync(CancellationToken.None).GetAwaiter().GetResult(); - _mockCluster.Verify(c => c.SelectServerAsync(It.IsAny(), CancellationToken.None), Times.Once); + _mockCluster.Verify(c => c.SelectServerAsync(It.IsAny(), null, CancellationToken.None), Times.Once); } else { - _mockCluster.Setup(c => c.SelectServer(It.IsAny(), CancellationToken.None)).Returns(selectedServer); + _mockCluster.Setup(c => c.SelectServer(It.IsAny(), null, CancellationToken.None)).Returns(selectedServer); subject.GetWriteChannelSource(CancellationToken.None); - _mockCluster.Verify(c => c.SelectServer(It.IsAny(), CancellationToken.None), Times.Once); + _mockCluster.Verify(c => c.SelectServer(It.IsAny(), null, CancellationToken.None), Times.Once); } } @@ -228,19 +228,19 @@ public void GetWriteChannelSource_with_mayUseSecondary_should_pass_mayUseSeconda if (async) { - _mockCluster.Setup(c => c.SelectServerAsync(It.IsAny(), CancellationToken.None)).Returns(Task.FromResult(selectedServer)); + _mockCluster.Setup(c => c.SelectServerAsync(It.IsAny(), null, CancellationToken.None)).Returns(Task.FromResult(selectedServer)); subject.GetWriteChannelSourceAsync(mayUseSecondary, CancellationToken.None).GetAwaiter().GetResult(); - _mockCluster.Verify(c => c.SelectServerAsync(It.Is(s => s.MayUseSecondary == mayUseSecondary), CancellationToken.None), Times.Once); + _mockCluster.Verify(c => c.SelectServerAsync(It.Is(s => s.MayUseSecondary == mayUseSecondary), null, CancellationToken.None), Times.Once); } else { - _mockCluster.Setup(c => c.SelectServer(It.IsAny(), CancellationToken.None)).Returns(selectedServer); + _mockCluster.Setup(c => c.SelectServer(It.IsAny(), null, CancellationToken.None)).Returns(selectedServer); subject.GetWriteChannelSource(mayUseSecondary, CancellationToken.None); - _mockCluster.Verify(c => c.SelectServer(It.Is(s => s.MayUseSecondary == mayUseSecondary), CancellationToken.None), Times.Once); + _mockCluster.Verify(c => c.SelectServer(It.Is(s => s.MayUseSecondary == mayUseSecondary), null, CancellationToken.None), Times.Once); } } diff --git a/tests/MongoDB.Driver.Core.Tests/Core/Clusters/ClusterTests.cs b/tests/MongoDB.Driver.Core.Tests/Core/Clusters/ClusterTests.cs index 5d2014796ac..e00fb4f66e7 100644 --- a/tests/MongoDB.Driver.Core.Tests/Core/Clusters/ClusterTests.cs +++ b/tests/MongoDB.Driver.Core.Tests/Core/Clusters/ClusterTests.cs @@ -526,6 +526,10 @@ public void DescriptionChanged_should_be_raised_when_the_description_changes() int count = 0; var subject = CreateSubject(); subject.Initialize(); + + // clear the ClusterDescriptionChanged event from initializing the StubCluster + _capturedEvents.Clear(); + subject.DescriptionChanged += (o, e) => count++; subject.SetServerDescriptions(ServerDescriptionHelper.Connected(subject.Description.ClusterId)); diff --git a/tests/MongoDB.Driver.Tests/Encryption/ClientEncryptionTests.cs b/tests/MongoDB.Driver.Tests/Encryption/ClientEncryptionTests.cs index 7126b685cb7..a5456c9952c 100644 --- a/tests/MongoDB.Driver.Tests/Encryption/ClientEncryptionTests.cs +++ b/tests/MongoDB.Driver.Tests/Encryption/ClientEncryptionTests.cs @@ -140,10 +140,10 @@ public async Task CreateEncryptedCollection_should_handle_generated_key_when_sec mockServer.Setup(s => s.GetChannelAsync(It.IsAny())).ReturnsAsync(channel); mockCluster - .Setup(m => m.SelectServer(It.IsAny(), It.IsAny())) + .Setup(m => m.SelectServer(It.IsAny(), null, It.IsAny())) .Returns(mockServer.Object); mockCluster - .Setup(m => m.SelectServerAsync(It.IsAny(), It.IsAny())) + .Setup(m => m.SelectServerAsync(It.IsAny(), null, It.IsAny())) .ReturnsAsync(mockServer.Object); var database = Mock.Of(d => @@ -229,10 +229,10 @@ public async Task CreateEncryptedCollection_should_handle_various_encryptedField mockServer.Setup(s => s.GetChannelAsync(It.IsAny())).ReturnsAsync(channel); mockCluster - .Setup(m => m.SelectServer(It.IsAny(), It.IsAny())) + .Setup(m => m.SelectServer(It.IsAny(), null, It.IsAny())) .Returns(mockServer.Object); mockCluster - .Setup(m => m.SelectServerAsync(It.IsAny(), It.IsAny())) + .Setup(m => m.SelectServerAsync(It.IsAny(), null, It.IsAny())) .ReturnsAsync(mockServer.Object); var database = Mock.Of(d => From d123f0792abc8384500b93799624a932e49e528b Mon Sep 17 00:00:00 2001 From: adelinowona Date: Fri, 12 Apr 2024 15:28:52 -0400 Subject: [PATCH 06/24] change events capturing method for prose tests --- .../RetryableReadsProseTests.cs | 33 ++++++++----------- .../prose-tests/RetryWriteOnOtherMongos.cs | 33 ++++++++----------- 2 files changed, 26 insertions(+), 40 deletions(-) diff --git a/tests/MongoDB.Driver.Tests/Specifications/retryable-reads/RetryableReadsProseTests.cs b/tests/MongoDB.Driver.Tests/Specifications/retryable-reads/RetryableReadsProseTests.cs index 9d6eeebaa06..e0415e6028e 100644 --- a/tests/MongoDB.Driver.Tests/Specifications/retryable-reads/RetryableReadsProseTests.cs +++ b/tests/MongoDB.Driver.Tests/Specifications/retryable-reads/RetryableReadsProseTests.cs @@ -147,8 +147,7 @@ public void Sharded_cluster_retryable_reads_are_retried_on_different_mongos_if_a } }"); - var eventCapturer = new EventCapturer() - .Capture(); + var eventCapturer = new EventCapturer().CaptureCommandEvents("find"); using var client = DriverTestConfiguration.CreateDisposableClient( s => @@ -172,12 +171,11 @@ public void Sharded_cluster_retryable_reads_are_retried_on_different_mongos_if_a collection.Find(Builders.Filter.Empty).ToList(); }); - eventCapturer.Events.OfType().Count().Should().Be(2); + var failedEvents = eventCapturer.Events.OfType().ToArray(); + failedEvents.Length.Should().Be(2); - var event1 = eventCapturer.Events[0].As(); - var event2 = eventCapturer.Events[1].As(); - event1.CommandName.Should().Be(event2.CommandName).And.Be("find"); - event1.ConnectionId.ServerId().Should().NotBe(event2.ConnectionId.ServerId()); + failedEvents[0].CommandName.Should().Be(failedEvents[1].CommandName).And.Be("find"); + failedEvents[0].ConnectionId.ServerId().Should().NotBe(failedEvents[1].ConnectionId.ServerId()); // Assert the deprioritization debug message was emitted for deprioritized server. Logs.Count(log => log.Category == "MongoDB.ServerSelection" && log.Message.StartsWith("Deprioritization")).Should().Be(1); @@ -201,9 +199,7 @@ public void Sharded_cluster_retryable_reads_are_retried_on_same_mongo_if_no_othe } }"); - var eventCapturer = new EventCapturer() - .Capture() - .Capture(); + var eventCapturer = new EventCapturer().CaptureCommandEvents("find"); using var client = DriverTestConfiguration.CreateDisposableClient( s => @@ -221,19 +217,16 @@ public void Sharded_cluster_retryable_reads_are_retried_on_same_mongo_if_no_othe var database = client.GetDatabase(DriverTestConfiguration.DatabaseNamespace.DatabaseName); var collection = database.GetCollection(DriverTestConfiguration.CollectionNamespace.CollectionName); - // clear command succeeded events captured from initial hello - eventCapturer.Clear(); - collection.Find(Builders.Filter.Empty).ToList(); - eventCapturer.Events.Count.Should().Be(2); - eventCapturer.Events.OfType().Count().Should().Be(1); - eventCapturer.Events.OfType().Count().Should().Be(1); + var failedEvents = eventCapturer.Events.OfType().ToArray(); + var succeededEvents = eventCapturer.Events.OfType().ToArray(); + + failedEvents.Length.Should().Be(1); + succeededEvents.Length.Should().Be(1); - var event1 = eventCapturer.Events[0].As(); - var event2 = eventCapturer.Events[1].As(); - event1.CommandName.Should().Be(event2.CommandName).And.Be("find"); - event1.ConnectionId.ServerId().Should().Be(event2.ConnectionId.ServerId()); + failedEvents[0].CommandName.Should().Be(succeededEvents[0].CommandName).And.Be("find"); + failedEvents[0].ConnectionId.ServerId().Should().Be(succeededEvents[0].ConnectionId.ServerId()); // Assert the deprioritization debug messages were emitted // one for deprioritizing the failpointServer and another for diff --git a/tests/MongoDB.Driver.Tests/Specifications/retryable-writes/prose-tests/RetryWriteOnOtherMongos.cs b/tests/MongoDB.Driver.Tests/Specifications/retryable-writes/prose-tests/RetryWriteOnOtherMongos.cs index e0dd24f5232..82e9a5b861c 100644 --- a/tests/MongoDB.Driver.Tests/Specifications/retryable-writes/prose-tests/RetryWriteOnOtherMongos.cs +++ b/tests/MongoDB.Driver.Tests/Specifications/retryable-writes/prose-tests/RetryWriteOnOtherMongos.cs @@ -57,8 +57,7 @@ public void Sharded_cluster_retryable_writes_are_retried_on_different_mongos_if_ } }"); - var eventCapturer = new EventCapturer() - .Capture(); + var eventCapturer = new EventCapturer().CaptureCommandEvents("insert"); using var client = DriverTestConfiguration.CreateDisposableClient( s => @@ -82,12 +81,11 @@ public void Sharded_cluster_retryable_writes_are_retried_on_different_mongos_if_ collection.InsertOne(new BsonDocument("x", 1)); }); - eventCapturer.Events.OfType().Count().Should().Be(2); + var failedEvents = eventCapturer.Events.OfType().ToArray(); + failedEvents.Length.Should().Be(2); - var event1 = eventCapturer.Events[0].As(); - var event2 = eventCapturer.Events[1].As(); - event1.CommandName.Should().Be(event2.CommandName).And.Be("insert"); - event1.ConnectionId.ServerId().Should().NotBe(event2.ConnectionId.ServerId()); + failedEvents[0].CommandName.Should().Be(failedEvents[1].CommandName).And.Be("insert"); + failedEvents[0].ConnectionId.ServerId().Should().NotBe(failedEvents[1].ConnectionId.ServerId()); // Assert the deprioritization debug message was emitted for deprioritized server. Logs.Count(log => log.Category == "MongoDB.ServerSelection" && log.Message.StartsWith("Deprioritization")).Should().Be(1); @@ -112,9 +110,7 @@ public void Sharded_cluster_retryable_writes_are_retried_on_same_mongo_if_no_oth } }"); - var eventCapturer = new EventCapturer() - .Capture() - .Capture(); + var eventCapturer = new EventCapturer().CaptureCommandEvents("insert"); using var client = DriverTestConfiguration.CreateDisposableClient( s => @@ -132,19 +128,16 @@ public void Sharded_cluster_retryable_writes_are_retried_on_same_mongo_if_no_oth var database = client.GetDatabase(DriverTestConfiguration.DatabaseNamespace.DatabaseName); var collection = database.GetCollection(DriverTestConfiguration.CollectionNamespace.CollectionName); - // clear command succeeded events captured from initial hello - eventCapturer.Clear(); - collection.InsertOne(new BsonDocument("x", 1)); - eventCapturer.Events.Count.Should().Be(2); - eventCapturer.Events.OfType().Count().Should().Be(1); - eventCapturer.Events.OfType().Count().Should().Be(1); + var failedEvents = eventCapturer.Events.OfType().ToArray(); + var succeededEvents = eventCapturer.Events.OfType().ToArray(); + + failedEvents.Length.Should().Be(1); + succeededEvents.Length.Should().Be(1); - var event1 = eventCapturer.Events[0].As(); - var event2 = eventCapturer.Events[1].As(); - event1.CommandName.Should().Be(event2.CommandName).And.Be("insert"); - event1.ConnectionId.ServerId().Should().Be(event2.ConnectionId.ServerId()); + failedEvents[0].CommandName.Should().Be(succeededEvents[0].CommandName).And.Be("insert"); + failedEvents[0].ConnectionId.ServerId().Should().Be(succeededEvents[0].ConnectionId.ServerId()); // Assert the deprioritization debug messages were emitted // one for deprioritizing the failpointServer and another for From dd8218000d89ea30e177f5be5253c5a373b9369e Mon Sep 17 00:00:00 2001 From: adelinowona Date: Mon, 15 Apr 2024 14:45:24 -0400 Subject: [PATCH 07/24] fix failing retryable prose tests on evergreen --- .../Specifications/retryable-reads/RetryableReadsProseTests.cs | 2 +- .../retryable-writes/prose-tests/RetryWriteOnOtherMongos.cs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/MongoDB.Driver.Tests/Specifications/retryable-reads/RetryableReadsProseTests.cs b/tests/MongoDB.Driver.Tests/Specifications/retryable-reads/RetryableReadsProseTests.cs index e0415e6028e..f198c576268 100644 --- a/tests/MongoDB.Driver.Tests/Specifications/retryable-reads/RetryableReadsProseTests.cs +++ b/tests/MongoDB.Driver.Tests/Specifications/retryable-reads/RetryableReadsProseTests.cs @@ -208,7 +208,7 @@ public void Sharded_cluster_retryable_reads_are_retried_on_same_mongo_if_no_othe s.DirectConnection = false; s.ClusterConfigurator = b => b.Subscribe(eventCapturer); } - , LoggingSettings, true); + , LoggingSettings); var failPointServer = client.Cluster.SelectServer(new EndPointServerSelector(client.Cluster.Description.Servers[0].EndPoint), default); diff --git a/tests/MongoDB.Driver.Tests/Specifications/retryable-writes/prose-tests/RetryWriteOnOtherMongos.cs b/tests/MongoDB.Driver.Tests/Specifications/retryable-writes/prose-tests/RetryWriteOnOtherMongos.cs index 82e9a5b861c..2bddf884f17 100644 --- a/tests/MongoDB.Driver.Tests/Specifications/retryable-writes/prose-tests/RetryWriteOnOtherMongos.cs +++ b/tests/MongoDB.Driver.Tests/Specifications/retryable-writes/prose-tests/RetryWriteOnOtherMongos.cs @@ -119,7 +119,7 @@ public void Sharded_cluster_retryable_writes_are_retried_on_same_mongo_if_no_oth s.DirectConnection = false; s.ClusterConfigurator = b => b.Subscribe(eventCapturer); } - , LoggingSettings, true); + , LoggingSettings); var failPointServer = client.Cluster.SelectServer(new EndPointServerSelector(client.Cluster.Description.Servers[0].EndPoint), default); From bef0c3710baf1061f87984d9baf75d490c923f04 Mon Sep 17 00:00:00 2001 From: adelinowona Date: Mon, 22 Apr 2024 15:43:19 -0400 Subject: [PATCH 08/24] refactor deprioritization mechanism --- .../Core/Clusters/Cluster.cs | 78 +++++++++++-------- 1 file changed, 47 insertions(+), 31 deletions(-) diff --git a/src/MongoDB.Driver.Core/Core/Clusters/Cluster.cs b/src/MongoDB.Driver.Core/Core/Clusters/Cluster.cs index 309203d8d6d..ec6f008c797 100644 --- a/src/MongoDB.Driver.Core/Core/Clusters/Cluster.cs +++ b/src/MongoDB.Driver.Core/Core/Clusters/Cluster.cs @@ -516,41 +516,19 @@ public IServer SelectServer(IReadOnlyCollection deprioritized _connectedServers.Clear(); _connectedServerDescriptions.Clear(); - var excludingDeprioritizedServers = deprioritizedServers != null && _cluster.Description.Type == ClusterType.Sharded; + var excludingDeprioritizedServers = deprioritizedServers?.Any() == true && _cluster.Description.Type == ClusterType.Sharded; - foreach (var description in _description.Servers) - { - if (!excludingDeprioritizedServers || !deprioritizedServers.Contains(description)) - { - if (description.State == ServerState.Connected && - _cluster.TryGetServer(description.EndPoint, out var server)) - { - _connectedServers.Add(server); - _connectedServerDescriptions.Add(description); - } - } - else - { - _cluster._serverSelectionEventLogger.Logger.LogDebug(_cluster._clusterId, - $"Deprioritization: removed server {description.ServerId}"); - } - } + var filteredServers = excludingDeprioritizedServers + ? FilterDeprioritizedServers(deprioritizedServers) + : _description.Servers; - // if we didn't get any connected servers from the previous look through candidates above - // and we are currently excluding deprioritized servers then it possible that all the - // candidates were part of the deprioritized collection. In this case, we just try to - // use the deprioritized servers. - if (excludingDeprioritizedServers && _connectedServers.Count == 0) + foreach (var description in filteredServers) { - _cluster._serverSelectionEventLogger.Logger.LogDebug(_cluster._clusterId, "Deprioritization: reverting due to no other suitable servers"); - foreach (var description in deprioritizedServers) + if (description.State == ServerState.Connected && + _cluster.TryGetServer(description.EndPoint, out var server)) { - if (description.State == ServerState.Connected && - _cluster.TryGetServer(description.EndPoint, out var server)) - { - _connectedServers.Add(server); - _connectedServerDescriptions.Add(description); - } + _connectedServers.Add(server); + _connectedServerDescriptions.Add(description); } } @@ -622,6 +600,31 @@ private IServerSelector DecorateSelector(IServerSelector selector) return new CompositeServerSelector(allSelectors); } + + private IReadOnlyList FilterDeprioritizedServers(IReadOnlyCollection deprioritizedServers) + { + List filteredServers = new(); + foreach (var description in _description.Servers) + { + if (!deprioritizedServers.Contains(description, new ServerDescriptionComparer())) + { + filteredServers.Add(description); + } + else + { + _cluster._serverSelectionEventLogger.Logger?.LogDebug(_cluster._clusterId, + $"Deprioritization: removed server {description.ServerId}"); + } + } + + if (filteredServers.Count == 0) + { + _cluster._serverSelectionEventLogger.Logger?.LogDebug(_cluster._clusterId, "Deprioritization: reverting due to no other suitable servers"); + return _description.Servers; + } + + return filteredServers; + } } private sealed class WaitForDescriptionChangedHelper : IDisposable @@ -685,6 +688,19 @@ public void HandleCompletedTask(Task completedTask) } } + private class ServerDescriptionComparer : IEqualityComparer + { + public bool Equals(ServerDescription x, ServerDescription y) + { + return x != null && y != null && x.EndPoint == y.EndPoint; + } + + public int GetHashCode(ServerDescription obj) + { + return obj.EndPoint.GetHashCode(); + } + } + private static class State { public const int Initial = 0; From 49995fd69a7620b9b0af96269a00310e654995f1 Mon Sep 17 00:00:00 2001 From: adelinowona Date: Tue, 23 Apr 2024 12:23:01 -0400 Subject: [PATCH 09/24] Incorporate review feedback --- .../Core/Bindings/ChannelReadBinding.cs | 20 ++---- .../Core/Bindings/ChannelReadWriteBinding.cs | 56 +++------------ .../Bindings/ChannelSourceReadWriteBinding.cs | 56 +++------------ .../Core/Bindings/IBinding.cs | 68 ++++--------------- .../Core/Bindings/ReadBindingHandle.cs | 23 ++----- .../Core/Bindings/ReadPreferenceBinding.cs | 16 +---- .../Core/Bindings/ReadWriteBindingHandle.cs | 67 ++++-------------- .../Core/Bindings/SingleServerReadBinding.cs | 20 ++---- .../Bindings/SingleServerReadWriteBinding.cs | 56 +++------------ .../Core/Bindings/WritableServerBinding.cs | 48 ++----------- .../RetryableReadOperationExecutor.cs | 4 +- .../RetryableWriteOperationExecutor.cs | 4 +- .../Core/Bindings/ReadBindingHandleTests.cs | 4 +- .../Bindings/ReadWriteBindingHandleTests.cs | 8 +-- .../Core/Clusters/ClusterTests.cs | 57 +++++++++++++--- .../Operations/ReadCommandOperationTests.cs | 4 +- .../RetryableWriteOperationExecutorTests.cs | 2 +- .../Operations/WriteCommandOperationTests.cs | 4 +- 18 files changed, 136 insertions(+), 381 deletions(-) diff --git a/src/MongoDB.Driver.Core/Core/Bindings/ChannelReadBinding.cs b/src/MongoDB.Driver.Core/Core/Bindings/ChannelReadBinding.cs index c91671dfa75..ff5699f60c0 100644 --- a/src/MongoDB.Driver.Core/Core/Bindings/ChannelReadBinding.cs +++ b/src/MongoDB.Driver.Core/Core/Bindings/ChannelReadBinding.cs @@ -75,32 +75,20 @@ public void Dispose() } } - /// - public IChannelSourceHandle GetReadChannelSource(CancellationToken cancellationToken) + /// + public IChannelSourceHandle GetReadChannelSource(CancellationToken cancellationToken, IReadOnlyCollection deprioritizedServers = null) { ThrowIfDisposed(); return GetReadChannelSourceHelper(); } - /// - public Task GetReadChannelSourceAsync(CancellationToken cancellationToken) + /// + public Task GetReadChannelSourceAsync(CancellationToken cancellationToken, IReadOnlyCollection deprioritizedServers = null) { ThrowIfDisposed(); return Task.FromResult(GetReadChannelSourceHelper()); } - /// - public IChannelSourceHandle GetReadChannelSource(IReadOnlyCollection deprioritizedServers, CancellationToken cancellationToken) - { - return GetReadChannelSource(cancellationToken); - } - - /// - public Task GetReadChannelSourceAsync(IReadOnlyCollection deprioritizedServers, CancellationToken cancellationToken) - { - return GetReadChannelSourceAsync(cancellationToken); - } - private IChannelSourceHandle GetReadChannelSourceHelper() { return new ChannelSourceHandle(new ChannelChannelSource(_server, _channel.Fork(), _session.Fork())); diff --git a/src/MongoDB.Driver.Core/Core/Bindings/ChannelReadWriteBinding.cs b/src/MongoDB.Driver.Core/Core/Bindings/ChannelReadWriteBinding.cs index 2e8bf6695f3..29624f77cf4 100644 --- a/src/MongoDB.Driver.Core/Core/Bindings/ChannelReadWriteBinding.cs +++ b/src/MongoDB.Driver.Core/Core/Bindings/ChannelReadWriteBinding.cs @@ -72,80 +72,44 @@ public void Dispose() } } - /// - public IChannelSourceHandle GetReadChannelSource(CancellationToken cancellationToken) + /// + public IChannelSourceHandle GetReadChannelSource(CancellationToken cancellationToken, IReadOnlyCollection deprioritizedServers = null) { ThrowIfDisposed(); return GetChannelSourceHelper(); } - /// - public Task GetReadChannelSourceAsync(CancellationToken cancellationToken) + /// + public Task GetReadChannelSourceAsync(CancellationToken cancellationToken, IReadOnlyCollection deprioritizedServers = null) { ThrowIfDisposed(); return Task.FromResult(GetChannelSourceHelper()); } /// - public IChannelSourceHandle GetReadChannelSource(IReadOnlyCollection deprioritizedServers, CancellationToken cancellationToken) - { - return GetReadChannelSource(cancellationToken); - } - - /// - public Task GetReadChannelSourceAsync(IReadOnlyCollection deprioritizedServers, CancellationToken cancellationToken) - { - return GetReadChannelSourceAsync(cancellationToken); - } - - /// - public IChannelSourceHandle GetWriteChannelSource(CancellationToken cancellationToken) + public IChannelSourceHandle GetWriteChannelSource(CancellationToken cancellationToken, IReadOnlyCollection deprioritizedServers = null) { ThrowIfDisposed(); return GetChannelSourceHelper(); } /// - public IChannelSourceHandle GetWriteChannelSource(IReadOnlyCollection deprioritizedServers, CancellationToken cancellationToken) - { - return GetWriteChannelSource(cancellationToken); - } - - /// - public IChannelSourceHandle GetWriteChannelSource(IMayUseSecondaryCriteria mayUseSecondary, CancellationToken cancellationToken) + public IChannelSourceHandle GetWriteChannelSource(IMayUseSecondaryCriteria mayUseSecondary, CancellationToken cancellationToken, IReadOnlyCollection deprioritizedServers = null) { - return GetWriteChannelSource(cancellationToken); // ignore mayUseSecondary + return GetWriteChannelSource(cancellationToken, deprioritizedServers); // ignore mayUseSecondary } /// - public IChannelSourceHandle GetWriteChannelSource(IReadOnlyCollection deprioritizedServers, IMayUseSecondaryCriteria mayUseSecondary, CancellationToken cancellationToken) - { - return GetWriteChannelSource(mayUseSecondary, cancellationToken); - } - - /// - public Task GetWriteChannelSourceAsync(CancellationToken cancellationToken) + public Task GetWriteChannelSourceAsync(CancellationToken cancellationToken, IReadOnlyCollection deprioritizedServers = null) { ThrowIfDisposed(); return Task.FromResult(GetChannelSourceHelper()); } /// - public Task GetWriteChannelSourceAsync(IReadOnlyCollection deprioritizedServers, CancellationToken cancellationToken) - { - return GetWriteChannelSourceAsync(cancellationToken); - } - - /// - public Task GetWriteChannelSourceAsync(IMayUseSecondaryCriteria mayUseSecondary, CancellationToken cancellationToken) - { - return GetWriteChannelSourceAsync(cancellationToken); // ignore mayUseSecondary - } - - /// - public Task GetWriteChannelSourceAsync(IReadOnlyCollection deprioritizedServers, IMayUseSecondaryCriteria mayUseSecondary, CancellationToken cancellationToken) + public Task GetWriteChannelSourceAsync(IMayUseSecondaryCriteria mayUseSecondary, CancellationToken cancellationToken, IReadOnlyCollection deprioritizedServers = null) { - return GetWriteChannelSourceAsync(mayUseSecondary, cancellationToken); + return GetWriteChannelSourceAsync(cancellationToken, deprioritizedServers); // ignore mayUseSecondary } // private methods diff --git a/src/MongoDB.Driver.Core/Core/Bindings/ChannelSourceReadWriteBinding.cs b/src/MongoDB.Driver.Core/Core/Bindings/ChannelSourceReadWriteBinding.cs index e434a36a57b..6aa976db82a 100644 --- a/src/MongoDB.Driver.Core/Core/Bindings/ChannelSourceReadWriteBinding.cs +++ b/src/MongoDB.Driver.Core/Core/Bindings/ChannelSourceReadWriteBinding.cs @@ -61,80 +61,44 @@ public ICoreSessionHandle Session } // methods - /// - public IChannelSourceHandle GetReadChannelSource(CancellationToken cancellationToken) + /// + public IChannelSourceHandle GetReadChannelSource(CancellationToken cancellationToken, IReadOnlyCollection deprioritizedServers = null) { ThrowIfDisposed(); return GetChannelSourceHelper(); } - /// - public Task GetReadChannelSourceAsync(CancellationToken cancellationToken) + /// + public Task GetReadChannelSourceAsync(CancellationToken cancellationToken, IReadOnlyCollection deprioritizedServers = null) { ThrowIfDisposed(); return Task.FromResult(GetChannelSourceHelper()); } /// - public IChannelSourceHandle GetReadChannelSource(IReadOnlyCollection deprioritizedServers, CancellationToken cancellationToken) - { - return GetReadChannelSource(cancellationToken); - } - - /// - public Task GetReadChannelSourceAsync(IReadOnlyCollection deprioritizedServers, CancellationToken cancellationToken) - { - return GetReadChannelSourceAsync(cancellationToken); - } - - /// - public IChannelSourceHandle GetWriteChannelSource(CancellationToken cancellationToken) + public IChannelSourceHandle GetWriteChannelSource(CancellationToken cancellationToken, IReadOnlyCollection deprioritizedServers = null) { ThrowIfDisposed(); return GetChannelSourceHelper(); } /// - public IChannelSourceHandle GetWriteChannelSource(IReadOnlyCollection deprioritizedServers, CancellationToken cancellationToken) - { - return GetWriteChannelSource(cancellationToken); - } - - /// - public IChannelSourceHandle GetWriteChannelSource(IMayUseSecondaryCriteria mayUseSecondary, CancellationToken cancellationToken) + public IChannelSourceHandle GetWriteChannelSource(IMayUseSecondaryCriteria mayUseSecondary, CancellationToken cancellationToken, IReadOnlyCollection deprioritizedServers = null) { - return GetWriteChannelSource(cancellationToken); // ignore mayUseSecondary + return GetWriteChannelSource(cancellationToken, deprioritizedServers); // ignore mayUseSecondary } /// - public IChannelSourceHandle GetWriteChannelSource(IReadOnlyCollection deprioritizedServers, IMayUseSecondaryCriteria mayUseSecondary, CancellationToken cancellationToken) - { - return GetWriteChannelSource(mayUseSecondary, cancellationToken); - } - - /// - public Task GetWriteChannelSourceAsync(CancellationToken cancellationToken) + public Task GetWriteChannelSourceAsync(CancellationToken cancellationToken, IReadOnlyCollection deprioritizedServers = null) { ThrowIfDisposed(); return Task.FromResult(GetChannelSourceHelper()); } /// - public Task GetWriteChannelSourceAsync(IReadOnlyCollection deprioritizedServers, CancellationToken cancellationToken) - { - return GetWriteChannelSourceAsync(cancellationToken); - } - - /// - public Task GetWriteChannelSourceAsync(IMayUseSecondaryCriteria mayUseSecondary, CancellationToken cancellationToken) - { - return GetWriteChannelSourceAsync(cancellationToken); // ignore mayUseSecondary - } - - /// - public Task GetWriteChannelSourceAsync(IReadOnlyCollection deprioritizedServers, IMayUseSecondaryCriteria mayUseSecondary, CancellationToken cancellationToken) + public Task GetWriteChannelSourceAsync(IMayUseSecondaryCriteria mayUseSecondary, CancellationToken cancellationToken, IReadOnlyCollection deprioritizedServers = null) { - return GetWriteChannelSourceAsync(mayUseSecondary, cancellationToken); + return GetWriteChannelSourceAsync(cancellationToken, deprioritizedServers); // ignore mayUseSecondary } /// diff --git a/src/MongoDB.Driver.Core/Core/Bindings/IBinding.cs b/src/MongoDB.Driver.Core/Core/Bindings/IBinding.cs index 40c33ee441c..1f6106af757 100644 --- a/src/MongoDB.Driver.Core/Core/Bindings/IBinding.cs +++ b/src/MongoDB.Driver.Core/Core/Bindings/IBinding.cs @@ -49,35 +49,21 @@ public interface IReadBinding : IBinding /// ReadPreference ReadPreference { get; } - /// - /// Gets a channel source for read operations. - /// - /// The cancellation token. - /// A channel source. - IChannelSourceHandle GetReadChannelSource(CancellationToken cancellationToken); - - /// - /// Gets a channel source for read operations. - /// - /// The cancellation token. - /// A channel source. - Task GetReadChannelSourceAsync(CancellationToken cancellationToken); - /// /// Gets a channel source for read operations while deprioritizing servers in the provided collection. /// - /// The deprioritized servers. /// The cancellation token. + /// The deprioritized servers. /// A channel source. - IChannelSourceHandle GetReadChannelSource(IReadOnlyCollection deprioritizedServers, CancellationToken cancellationToken); + IChannelSourceHandle GetReadChannelSource(CancellationToken cancellationToken, IReadOnlyCollection deprioritizedServers = null); /// /// Gets a channel source for read operations while deprioritizing servers in the provided collection. /// - /// The deprioritized servers. /// The cancellation token. + /// The deprioritized servers. /// A channel source. - Task GetReadChannelSourceAsync(IReadOnlyCollection deprioritizedServers, CancellationToken cancellationToken); + Task GetReadChannelSourceAsync(CancellationToken cancellationToken, IReadOnlyCollection deprioritizedServers = null); } /// @@ -85,69 +71,39 @@ public interface IReadBinding : IBinding /// public interface IWriteBinding : IBinding { - /// - /// Gets a channel source for write operations. - /// - /// The cancellation token. - /// A channel source. - IChannelSourceHandle GetWriteChannelSource(CancellationToken cancellationToken); - /// /// Gets a channel source for write operations while deprioritizing servers in the provided collection. /// - /// The deprioritized servers. - /// The cancellation token. - /// A channel source. - IChannelSourceHandle GetWriteChannelSource(IReadOnlyCollection deprioritizedServers, CancellationToken cancellationToken); - - /// - /// Gets a channel source for write operations that may use a secondary. - /// - /// The may use secondary criteria. /// The cancellation token. + /// The deprioritized servers. /// A channel source. - IChannelSourceHandle GetWriteChannelSource(IMayUseSecondaryCriteria mayUseSecondary, CancellationToken cancellationToken); + IChannelSourceHandle GetWriteChannelSource(CancellationToken cancellationToken, IReadOnlyCollection deprioritizedServers = null); /// /// Gets a channel source for write operations that may use a secondary and deprioritizes servers in the provided collection. /// - /// The deprioritized servers. /// The may use secondary criteria. /// The cancellation token. - /// A channel source. - IChannelSourceHandle GetWriteChannelSource(IReadOnlyCollection deprioritizedServers, IMayUseSecondaryCriteria mayUseSecondary, CancellationToken cancellationToken); - - /// - /// Gets a channel source for write operations. - /// - /// The cancellation token. - /// A channel source. - Task GetWriteChannelSourceAsync(CancellationToken cancellationToken); - - /// - /// Gets a channel source for write operations while deprioritizing servers in the provided collection. - /// /// The deprioritized servers. - /// The cancellation token. /// A channel source. - Task GetWriteChannelSourceAsync(IReadOnlyCollection deprioritizedServers, CancellationToken cancellationToken); + IChannelSourceHandle GetWriteChannelSource(IMayUseSecondaryCriteria mayUseSecondary, CancellationToken cancellationToken, IReadOnlyCollection deprioritizedServers = null); /// - /// Gets a channel source for write operations that may use a secondary. + /// Gets a channel source for write operations while deprioritizing servers in the provided collection. /// - /// The may use secondary criteria. /// The cancellation token. + /// The deprioritized servers. /// A channel source. - Task GetWriteChannelSourceAsync(IMayUseSecondaryCriteria mayUseSecondary, CancellationToken cancellationToken); + Task GetWriteChannelSourceAsync(CancellationToken cancellationToken, IReadOnlyCollection deprioritizedServers = null); /// /// Gets a channel source for write operations that may use a secondary and deprioritizes servers in the provided collection. /// - /// The deprioritized servers. /// The may use secondary criteria. /// The cancellation token. + /// The deprioritized servers. /// A channel source. - Task GetWriteChannelSourceAsync(IReadOnlyCollection deprioritizedServers, IMayUseSecondaryCriteria mayUseSecondary, CancellationToken cancellationToken); + Task GetWriteChannelSourceAsync(IMayUseSecondaryCriteria mayUseSecondary, CancellationToken cancellationToken, IReadOnlyCollection deprioritizedServers = null); } /// diff --git a/src/MongoDB.Driver.Core/Core/Bindings/ReadBindingHandle.cs b/src/MongoDB.Driver.Core/Core/Bindings/ReadBindingHandle.cs index 6c8283d2bfd..8d9e448f5db 100644 --- a/src/MongoDB.Driver.Core/Core/Bindings/ReadBindingHandle.cs +++ b/src/MongoDB.Driver.Core/Core/Bindings/ReadBindingHandle.cs @@ -59,33 +59,18 @@ public ICoreSessionHandle Session get { return _reference.Instance.Session; } } - // methods - /// - public IChannelSourceHandle GetReadChannelSource(CancellationToken cancellationToken) - { - ThrowIfDisposed(); - return _reference.Instance.GetReadChannelSource(cancellationToken); - } - - /// - public Task GetReadChannelSourceAsync(CancellationToken cancellationToken) - { - ThrowIfDisposed(); - return _reference.Instance.GetReadChannelSourceAsync(cancellationToken); - } - /// - public IChannelSourceHandle GetReadChannelSource(IReadOnlyCollection deprioritizedServers, CancellationToken cancellationToken) + public IChannelSourceHandle GetReadChannelSource(CancellationToken cancellationToken, IReadOnlyCollection deprioritizedServers = null) { ThrowIfDisposed(); - return _reference.Instance.GetReadChannelSource(deprioritizedServers, cancellationToken); + return _reference.Instance.GetReadChannelSource(cancellationToken, deprioritizedServers); } /// - public Task GetReadChannelSourceAsync(IReadOnlyCollection deprioritizedServers, CancellationToken cancellationToken) + public Task GetReadChannelSourceAsync(CancellationToken cancellationToken, IReadOnlyCollection deprioritizedServers = null) { ThrowIfDisposed(); - return _reference.Instance.GetReadChannelSourceAsync(deprioritizedServers, cancellationToken); + return _reference.Instance.GetReadChannelSourceAsync(cancellationToken, deprioritizedServers); } /// diff --git a/src/MongoDB.Driver.Core/Core/Bindings/ReadPreferenceBinding.cs b/src/MongoDB.Driver.Core/Core/Bindings/ReadPreferenceBinding.cs index 4bd662f53a7..26c0868463a 100644 --- a/src/MongoDB.Driver.Core/Core/Bindings/ReadPreferenceBinding.cs +++ b/src/MongoDB.Driver.Core/Core/Bindings/ReadPreferenceBinding.cs @@ -65,20 +65,8 @@ public ICoreSessionHandle Session } // methods - /// - public IChannelSourceHandle GetReadChannelSource(CancellationToken cancellationToken) - { - return GetReadChannelSource(null, cancellationToken); - } - - /// - public async Task GetReadChannelSourceAsync(CancellationToken cancellationToken) - { - return await GetReadChannelSourceAsync(null, cancellationToken).ConfigureAwait(false); - } - /// - public IChannelSourceHandle GetReadChannelSource(IReadOnlyCollection deprioritizedServers, CancellationToken cancellationToken) + public IChannelSourceHandle GetReadChannelSource(CancellationToken cancellationToken, IReadOnlyCollection deprioritizedServers = null) { ThrowIfDisposed(); var server = _cluster.SelectServerAndPinIfNeeded(_session, _serverSelector, deprioritizedServers, cancellationToken); @@ -86,7 +74,7 @@ public IChannelSourceHandle GetReadChannelSource(IReadOnlyCollection - public async Task GetReadChannelSourceAsync(IReadOnlyCollection deprioritizedServers, CancellationToken cancellationToken) + public async Task GetReadChannelSourceAsync(CancellationToken cancellationToken, IReadOnlyCollection deprioritizedServers = null) { ThrowIfDisposed(); var server = await _cluster.SelectServerAndPinIfNeededAsync(_session, _serverSelector, deprioritizedServers, cancellationToken).ConfigureAwait(false); diff --git a/src/MongoDB.Driver.Core/Core/Bindings/ReadWriteBindingHandle.cs b/src/MongoDB.Driver.Core/Core/Bindings/ReadWriteBindingHandle.cs index 205e47dfdf4..c43c4ab05c0 100644 --- a/src/MongoDB.Driver.Core/Core/Bindings/ReadWriteBindingHandle.cs +++ b/src/MongoDB.Driver.Core/Core/Bindings/ReadWriteBindingHandle.cs @@ -59,89 +59,46 @@ public ICoreSessionHandle Session get { return _reference.Instance.Session; } } - // methods - /// - public IChannelSourceHandle GetReadChannelSource(CancellationToken cancellationToken) - { - ThrowIfDisposed(); - return _reference.Instance.GetReadChannelSource(cancellationToken); - } - - /// - public Task GetReadChannelSourceAsync(CancellationToken cancellationToken) - { - ThrowIfDisposed(); - return _reference.Instance.GetReadChannelSourceAsync(cancellationToken); - } - /// - public IChannelSourceHandle GetReadChannelSource(IReadOnlyCollection deprioritizedServers, CancellationToken cancellationToken) + public IChannelSourceHandle GetReadChannelSource(CancellationToken cancellationToken, IReadOnlyCollection deprioritizedServers = null) { ThrowIfDisposed(); - return _reference.Instance.GetReadChannelSource(deprioritizedServers, cancellationToken); + return _reference.Instance.GetReadChannelSource(cancellationToken, deprioritizedServers); } /// - public Task GetReadChannelSourceAsync(IReadOnlyCollection deprioritizedServers, CancellationToken cancellationToken) - { - ThrowIfDisposed(); - return _reference.Instance.GetReadChannelSourceAsync(deprioritizedServers, cancellationToken); - } - - /// - public IChannelSourceHandle GetWriteChannelSource(CancellationToken cancellationToken) + public Task GetReadChannelSourceAsync(CancellationToken cancellationToken, IReadOnlyCollection deprioritizedServers = null) { ThrowIfDisposed(); - return _reference.Instance.GetWriteChannelSource(cancellationToken); + return _reference.Instance.GetReadChannelSourceAsync(cancellationToken, deprioritizedServers); } /// - public IChannelSourceHandle GetWriteChannelSource(IReadOnlyCollection deprioritizedServers, CancellationToken cancellationToken) + public IChannelSourceHandle GetWriteChannelSource(CancellationToken cancellationToken, IReadOnlyCollection deprioritizedServers = null) { ThrowIfDisposed(); - return _reference.Instance.GetWriteChannelSource(deprioritizedServers, cancellationToken); - } - - /// - public IChannelSourceHandle GetWriteChannelSource(IMayUseSecondaryCriteria mayUseSecondary, CancellationToken cancellationToken) - { - ThrowIfDisposed(); - return _reference.Instance.GetWriteChannelSource(mayUseSecondary, cancellationToken); + return _reference.Instance.GetWriteChannelSource(cancellationToken, deprioritizedServers); } /// - public IChannelSourceHandle GetWriteChannelSource(IReadOnlyCollection deprioritizedServers, IMayUseSecondaryCriteria mayUseSecondary, CancellationToken cancellationToken) + public IChannelSourceHandle GetWriteChannelSource(IMayUseSecondaryCriteria mayUseSecondary, CancellationToken cancellationToken, IReadOnlyCollection deprioritizedServers = null) { ThrowIfDisposed(); - return _reference.Instance.GetWriteChannelSource(deprioritizedServers, mayUseSecondary, cancellationToken); - } - - /// - public Task GetWriteChannelSourceAsync(CancellationToken cancellationToken) - { - ThrowIfDisposed(); - return _reference.Instance.GetWriteChannelSourceAsync(cancellationToken); + return _reference.Instance.GetWriteChannelSource(mayUseSecondary, cancellationToken, deprioritizedServers); } /// - public Task GetWriteChannelSourceAsync(IReadOnlyCollection deprioritizedServers, CancellationToken cancellationToken) - { - ThrowIfDisposed(); - return _reference.Instance.GetWriteChannelSourceAsync(deprioritizedServers, cancellationToken); - } - - /// - public Task GetWriteChannelSourceAsync(IMayUseSecondaryCriteria mayUseSecondary, CancellationToken cancellationToken) + public Task GetWriteChannelSourceAsync(CancellationToken cancellationToken, IReadOnlyCollection deprioritizedServers = null) { ThrowIfDisposed(); - return _reference.Instance.GetWriteChannelSourceAsync(mayUseSecondary, cancellationToken); + return _reference.Instance.GetWriteChannelSourceAsync(cancellationToken, deprioritizedServers); } /// - public Task GetWriteChannelSourceAsync(IReadOnlyCollection deprioritizedServers, IMayUseSecondaryCriteria mayUseSecondary, CancellationToken cancellationToken) + public Task GetWriteChannelSourceAsync(IMayUseSecondaryCriteria mayUseSecondary, CancellationToken cancellationToken, IReadOnlyCollection deprioritizedServers = null) { ThrowIfDisposed(); - return _reference.Instance.GetWriteChannelSourceAsync(deprioritizedServers, mayUseSecondary, cancellationToken); + return _reference.Instance.GetWriteChannelSourceAsync(mayUseSecondary, cancellationToken, deprioritizedServers); } /// diff --git a/src/MongoDB.Driver.Core/Core/Bindings/SingleServerReadBinding.cs b/src/MongoDB.Driver.Core/Core/Bindings/SingleServerReadBinding.cs index 7666ef3e719..28cb59c095c 100644 --- a/src/MongoDB.Driver.Core/Core/Bindings/SingleServerReadBinding.cs +++ b/src/MongoDB.Driver.Core/Core/Bindings/SingleServerReadBinding.cs @@ -64,32 +64,20 @@ public ICoreSessionHandle Session } // methods - /// - public IChannelSourceHandle GetReadChannelSource(CancellationToken cancellationToken) + /// + public IChannelSourceHandle GetReadChannelSource(CancellationToken cancellationToken, IReadOnlyCollection deprioritizedServers = null) { ThrowIfDisposed(); return GetChannelSourceHelper(); } - /// - public Task GetReadChannelSourceAsync(CancellationToken cancellationToken) + /// + public Task GetReadChannelSourceAsync(CancellationToken cancellationToken, IReadOnlyCollection deprioritizedServers = null) { ThrowIfDisposed(); return Task.FromResult(GetChannelSourceHelper()); } - /// - public IChannelSourceHandle GetReadChannelSource(IReadOnlyCollection deprioritizedServers, CancellationToken cancellationToken) - { - return GetReadChannelSource(cancellationToken); - } - - /// - public Task GetReadChannelSourceAsync(IReadOnlyCollection deprioritizedServers, CancellationToken cancellationToken) - { - return GetReadChannelSourceAsync(cancellationToken); - } - /// public void Dispose() { diff --git a/src/MongoDB.Driver.Core/Core/Bindings/SingleServerReadWriteBinding.cs b/src/MongoDB.Driver.Core/Core/Bindings/SingleServerReadWriteBinding.cs index 8fec85d3249..ec849cde1f2 100644 --- a/src/MongoDB.Driver.Core/Core/Bindings/SingleServerReadWriteBinding.cs +++ b/src/MongoDB.Driver.Core/Core/Bindings/SingleServerReadWriteBinding.cs @@ -68,80 +68,44 @@ public void Dispose() } } - /// - public IChannelSourceHandle GetReadChannelSource(CancellationToken cancellationToken) + /// + public IChannelSourceHandle GetReadChannelSource(CancellationToken cancellationToken, IReadOnlyCollection deprioritizedServers = null) { ThrowIfDisposed(); return GetChannelSourceHelper(); } - /// - public Task GetReadChannelSourceAsync(CancellationToken cancellationToken) + /// + public Task GetReadChannelSourceAsync(CancellationToken cancellationToken, IReadOnlyCollection deprioritizedServers = null) { ThrowIfDisposed(); return Task.FromResult(GetChannelSourceHelper()); } /// - public IChannelSourceHandle GetReadChannelSource(IReadOnlyCollection deprioritizedServers, CancellationToken cancellationToken) - { - return GetReadChannelSource(cancellationToken); - } - - /// - public Task GetReadChannelSourceAsync(IReadOnlyCollection deprioritizedServers, CancellationToken cancellationToken) - { - return GetReadChannelSourceAsync(cancellationToken); - } - - /// - public IChannelSourceHandle GetWriteChannelSource(CancellationToken cancellationToken) + public IChannelSourceHandle GetWriteChannelSource(CancellationToken cancellationToken, IReadOnlyCollection deprioritizedServers = null) { ThrowIfDisposed(); return GetChannelSourceHelper(); } /// - public IChannelSourceHandle GetWriteChannelSource(IReadOnlyCollection deprioritizedServers, CancellationToken cancellationToken) - { - return GetWriteChannelSource(cancellationToken); - } - - /// - public IChannelSourceHandle GetWriteChannelSource(IMayUseSecondaryCriteria mayUseSecondary, CancellationToken cancellationToken) + public IChannelSourceHandle GetWriteChannelSource(IMayUseSecondaryCriteria mayUseSecondary, CancellationToken cancellationToken, IReadOnlyCollection deprioritizedServers = null) { - return GetWriteChannelSource(cancellationToken); // ignore mayUseSecondary + return GetWriteChannelSource(cancellationToken, deprioritizedServers); // ignore mayUseSecondary } /// - public IChannelSourceHandle GetWriteChannelSource(IReadOnlyCollection deprioritizedServers, IMayUseSecondaryCriteria mayUseSecondary, CancellationToken cancellationToken) - { - return GetWriteChannelSource(mayUseSecondary, cancellationToken); - } - - /// - public Task GetWriteChannelSourceAsync(CancellationToken cancellationToken) + public Task GetWriteChannelSourceAsync(CancellationToken cancellationToken, IReadOnlyCollection deprioritizedServers = null) { ThrowIfDisposed(); return Task.FromResult(GetChannelSourceHelper()); } /// - public Task GetWriteChannelSourceAsync(IReadOnlyCollection deprioritizedServers, CancellationToken cancellationToken) - { - return GetWriteChannelSourceAsync(cancellationToken); - } - - /// - public Task GetWriteChannelSourceAsync(IMayUseSecondaryCriteria mayUseSecondary, CancellationToken cancellationToken) - { - return GetWriteChannelSourceAsync(cancellationToken); // ignore mayUseSecondary - } - - /// - public Task GetWriteChannelSourceAsync(IReadOnlyCollection deprioritizedServers, IMayUseSecondaryCriteria mayUseSecondary, CancellationToken cancellationToken) + public Task GetWriteChannelSourceAsync(IMayUseSecondaryCriteria mayUseSecondary, CancellationToken cancellationToken, IReadOnlyCollection deprioritizedServers = null) { - return GetWriteChannelSourceAsync(mayUseSecondary, cancellationToken); + return GetWriteChannelSourceAsync(cancellationToken, deprioritizedServers); // ignore mayUseSecondary } private IChannelSourceHandle GetChannelSourceHelper() diff --git a/src/MongoDB.Driver.Core/Core/Bindings/WritableServerBinding.cs b/src/MongoDB.Driver.Core/Core/Bindings/WritableServerBinding.cs index 379adc02944..52d28a61914 100644 --- a/src/MongoDB.Driver.Core/Core/Bindings/WritableServerBinding.cs +++ b/src/MongoDB.Driver.Core/Core/Bindings/WritableServerBinding.cs @@ -60,20 +60,8 @@ public ICoreSessionHandle Session } // methods - /// - public IChannelSourceHandle GetReadChannelSource(CancellationToken cancellationToken) - { - return GetReadChannelSource(null, cancellationToken); - } - - /// - public async Task GetReadChannelSourceAsync(CancellationToken cancellationToken) - { - return await GetReadChannelSourceAsync(null, cancellationToken).ConfigureAwait(false); - } - /// - public IChannelSourceHandle GetReadChannelSource(IReadOnlyCollection deprioritizedServers, CancellationToken cancellationToken) + public IChannelSourceHandle GetReadChannelSource(CancellationToken cancellationToken, IReadOnlyCollection deprioritizedServers = null) { ThrowIfDisposed(); var server = _cluster.SelectServerAndPinIfNeeded(_session, WritableServerSelector.Instance, deprioritizedServers, cancellationToken); @@ -81,35 +69,23 @@ public IChannelSourceHandle GetReadChannelSource(IReadOnlyCollection - public async Task GetReadChannelSourceAsync(IReadOnlyCollection deprioritizedServers, CancellationToken cancellationToken) + public async Task GetReadChannelSourceAsync(CancellationToken cancellationToken, IReadOnlyCollection deprioritizedServers = null) { ThrowIfDisposed(); var server = await _cluster.SelectServerAndPinIfNeededAsync(_session, WritableServerSelector.Instance, deprioritizedServers, cancellationToken).ConfigureAwait(false); return CreateServerChannelSource(server); } - /// - public IChannelSourceHandle GetWriteChannelSource(CancellationToken cancellationToken) - { - return GetWriteChannelSource(deprioritizedServers: null, cancellationToken); - } - /// - public IChannelSourceHandle GetWriteChannelSource(IReadOnlyCollection deprioritizedServers, CancellationToken cancellationToken) + public IChannelSourceHandle GetWriteChannelSource(CancellationToken cancellationToken, IReadOnlyCollection deprioritizedServers = null) { ThrowIfDisposed(); var server = _cluster.SelectServerAndPinIfNeeded(_session, WritableServerSelector.Instance, deprioritizedServers, cancellationToken); return CreateServerChannelSource(server); } - /// - public IChannelSourceHandle GetWriteChannelSource(IMayUseSecondaryCriteria mayUseSecondary, CancellationToken cancellationToken) - { - return GetWriteChannelSource(null, mayUseSecondary, cancellationToken); - } - /// - public IChannelSourceHandle GetWriteChannelSource(IReadOnlyCollection deprioritizedServers, IMayUseSecondaryCriteria mayUseSecondary, CancellationToken cancellationToken) + public IChannelSourceHandle GetWriteChannelSource(IMayUseSecondaryCriteria mayUseSecondary, CancellationToken cancellationToken, IReadOnlyCollection deprioritizedServers = null) { if (IsSessionPinnedToServer()) { @@ -121,28 +97,16 @@ public IChannelSourceHandle GetWriteChannelSource(IReadOnlyCollection - public async Task GetWriteChannelSourceAsync(CancellationToken cancellationToken) - { - return await GetWriteChannelSourceAsync(deprioritizedServers: null, cancellationToken).ConfigureAwait(false); - } - /// - public async Task GetWriteChannelSourceAsync(IReadOnlyCollection deprioritizedServers, CancellationToken cancellationToken) + public async Task GetWriteChannelSourceAsync(CancellationToken cancellationToken, IReadOnlyCollection deprioritizedServers = null) { ThrowIfDisposed(); var server = await _cluster.SelectServerAndPinIfNeededAsync(_session, WritableServerSelector.Instance, deprioritizedServers, cancellationToken).ConfigureAwait(false); return CreateServerChannelSource(server); } - /// - public async Task GetWriteChannelSourceAsync(IMayUseSecondaryCriteria mayUseSecondary, CancellationToken cancellationToken) - { - return await GetWriteChannelSourceAsync(null, mayUseSecondary, cancellationToken).ConfigureAwait(false); - } - /// - public async Task GetWriteChannelSourceAsync(IReadOnlyCollection deprioritizedServers, IMayUseSecondaryCriteria mayUseSecondary, CancellationToken cancellationToken) + public async Task GetWriteChannelSourceAsync(IMayUseSecondaryCriteria mayUseSecondary, CancellationToken cancellationToken, IReadOnlyCollection deprioritizedServers = null) { if (IsSessionPinnedToServer()) { diff --git a/src/MongoDB.Driver.Core/Core/Operations/RetryableReadOperationExecutor.cs b/src/MongoDB.Driver.Core/Core/Operations/RetryableReadOperationExecutor.cs index cebcdf594a1..d460aa73f74 100644 --- a/src/MongoDB.Driver.Core/Core/Operations/RetryableReadOperationExecutor.cs +++ b/src/MongoDB.Driver.Core/Core/Operations/RetryableReadOperationExecutor.cs @@ -51,7 +51,7 @@ public static TResult Execute(IRetryableReadOperation operatio try { - context.ReplaceChannelSource(context.Binding.GetReadChannelSource(new []{ context.ChannelSource.ServerDescription }, cancellationToken)); + context.ReplaceChannelSource(context.Binding.GetReadChannelSource(cancellationToken, new [] { context.ChannelSource.ServerDescription })); context.ReplaceChannel(context.ChannelSource.GetChannel(cancellationToken)); } catch @@ -96,7 +96,7 @@ public static async Task ExecuteAsync(IRetryableReadOperation< try { - context.ReplaceChannelSource(context.Binding.GetReadChannelSource(new []{ context.ChannelSource.ServerDescription }, cancellationToken)); + context.ReplaceChannelSource(context.Binding.GetReadChannelSource(cancellationToken, new [] { context.ChannelSource.ServerDescription })); context.ReplaceChannel(context.ChannelSource.GetChannel(cancellationToken)); } catch diff --git a/src/MongoDB.Driver.Core/Core/Operations/RetryableWriteOperationExecutor.cs b/src/MongoDB.Driver.Core/Core/Operations/RetryableWriteOperationExecutor.cs index edb59aec00a..6f7ff56b974 100644 --- a/src/MongoDB.Driver.Core/Core/Operations/RetryableWriteOperationExecutor.cs +++ b/src/MongoDB.Driver.Core/Core/Operations/RetryableWriteOperationExecutor.cs @@ -53,7 +53,7 @@ public static TResult Execute(IRetryableWriteOperation operati try { - context.ReplaceChannelSource(context.Binding.GetWriteChannelSource(new []{ context.ChannelSource.ServerDescription }, cancellationToken)); + context.ReplaceChannelSource(context.Binding.GetWriteChannelSource(cancellationToken, new [] { context.ChannelSource.ServerDescription })); context.ReplaceChannel(context.ChannelSource.GetChannel(cancellationToken)); } catch @@ -104,7 +104,7 @@ public static async Task ExecuteAsync(IRetryableWriteOperation try { - context.ReplaceChannelSource(await context.Binding.GetWriteChannelSourceAsync(new []{ context.ChannelSource.ServerDescription }, cancellationToken).ConfigureAwait(false)); + context.ReplaceChannelSource(await context.Binding.GetWriteChannelSourceAsync(cancellationToken, new [] { context.ChannelSource.ServerDescription }).ConfigureAwait(false)); context.ReplaceChannel(await context.ChannelSource.GetChannelAsync(cancellationToken).ConfigureAwait(false)); } catch diff --git a/tests/MongoDB.Driver.Core.Tests/Core/Bindings/ReadBindingHandleTests.cs b/tests/MongoDB.Driver.Core.Tests/Core/Bindings/ReadBindingHandleTests.cs index d26b05ff749..2a089a050b2 100644 --- a/tests/MongoDB.Driver.Core.Tests/Core/Bindings/ReadBindingHandleTests.cs +++ b/tests/MongoDB.Driver.Core.Tests/Core/Bindings/ReadBindingHandleTests.cs @@ -83,13 +83,13 @@ public void GetReadChannelSource_should_delegate_to_reference( { subject.GetReadChannelSourceAsync(CancellationToken.None).GetAwaiter().GetResult(); - _mockReadBinding.Verify(b => b.GetReadChannelSourceAsync(CancellationToken.None), Times.Once); + _mockReadBinding.Verify(b => b.GetReadChannelSourceAsync(CancellationToken.None, null), Times.Once); } else { subject.GetReadChannelSource(CancellationToken.None); - _mockReadBinding.Verify(b => b.GetReadChannelSource(CancellationToken.None), Times.Once); + _mockReadBinding.Verify(b => b.GetReadChannelSource(CancellationToken.None, null), Times.Once); } } diff --git a/tests/MongoDB.Driver.Core.Tests/Core/Bindings/ReadWriteBindingHandleTests.cs b/tests/MongoDB.Driver.Core.Tests/Core/Bindings/ReadWriteBindingHandleTests.cs index 33f36397c1b..f5d7fb7dded 100644 --- a/tests/MongoDB.Driver.Core.Tests/Core/Bindings/ReadWriteBindingHandleTests.cs +++ b/tests/MongoDB.Driver.Core.Tests/Core/Bindings/ReadWriteBindingHandleTests.cs @@ -84,13 +84,13 @@ public void GetReadChannelSource_should_delegate_to_reference( { subject.GetReadChannelSourceAsync(CancellationToken.None).GetAwaiter().GetResult(); - _mockReadWriteBinding.Verify(b => b.GetReadChannelSourceAsync(CancellationToken.None), Times.Once); + _mockReadWriteBinding.Verify(b => b.GetReadChannelSourceAsync(CancellationToken.None, null), Times.Once); } else { subject.GetReadChannelSource(CancellationToken.None); - _mockReadWriteBinding.Verify(b => b.GetReadChannelSource(CancellationToken.None), Times.Once); + _mockReadWriteBinding.Verify(b => b.GetReadChannelSource(CancellationToken.None, null), Times.Once); } } @@ -128,13 +128,13 @@ public void GetWriteChannelSource_should_delegate_to_reference( { subject.GetWriteChannelSourceAsync(CancellationToken.None).GetAwaiter().GetResult(); - _mockReadWriteBinding.Verify(b => b.GetWriteChannelSourceAsync(CancellationToken.None), Times.Once); + _mockReadWriteBinding.Verify(b => b.GetWriteChannelSourceAsync(CancellationToken.None, null), Times.Once); } else { subject.GetWriteChannelSource(CancellationToken.None); - _mockReadWriteBinding.Verify(b => b.GetWriteChannelSource(CancellationToken.None), Times.Once); + _mockReadWriteBinding.Verify(b => b.GetWriteChannelSource(CancellationToken.None, null), Times.Once); } } diff --git a/tests/MongoDB.Driver.Core.Tests/Core/Clusters/ClusterTests.cs b/tests/MongoDB.Driver.Core.Tests/Core/Clusters/ClusterTests.cs index e00fb4f66e7..ce0d71c8f96 100644 --- a/tests/MongoDB.Driver.Core.Tests/Core/Clusters/ClusterTests.cs +++ b/tests/MongoDB.Driver.Core.Tests/Core/Clusters/ClusterTests.cs @@ -415,7 +415,7 @@ public void SelectServer_should_keep_trying_to_match_by_waiting_on_cluster_descr [Theory] [ParameterAttributeData] - public void SelectServer_should_ignore_deprioritized_servers_if_cluster_is_sharded( + public async void SelectServer_should_ignore_deprioritized_servers_if_cluster_is_sharded( [Values(false, true)] bool async) { @@ -436,6 +436,7 @@ public void SelectServer_should_ignore_deprioritized_servers_if_cluster_is_shard var selector = new DelegateServerSelector((c, s) => s); var deprioritizedServers = new List { connected1 }; + var deprioritizedServersEndpoints = deprioritizedServers.Select(description => description.EndPoint).ToList(); for (int i = 0; i < 15; i++) { @@ -444,7 +445,7 @@ public void SelectServer_should_ignore_deprioritized_servers_if_cluster_is_shard IServer result; if (async) { - result = subject.SelectServerAsync(selector, deprioritizedServers, CancellationToken.None).GetAwaiter().GetResult(); + result = await subject.SelectServerAsync(selector, deprioritizedServers, CancellationToken.None); } else { @@ -452,8 +453,6 @@ public void SelectServer_should_ignore_deprioritized_servers_if_cluster_is_shard } result.Should().NotBeNull(); - - var deprioritizedServersEndpoints = deprioritizedServers.Select(description => description.EndPoint); deprioritizedServersEndpoints.Should().NotContain(result.Description.EndPoint); _capturedEvents.Next().Should().BeOfType(); @@ -464,12 +463,51 @@ public void SelectServer_should_ignore_deprioritized_servers_if_cluster_is_shard [Theory] [ParameterAttributeData] - public void SelectServer_should_return_deprioritized_servers_if_no_other_servers_exist_or_cluster_not_sharded( + public async void SelectServer_should_not_deprioritize_if_there_no_servers_to_deprioritize( + [Values(false, true)] bool async) + { +#pragma warning disable CS0618 // Type or member is obsolete + var subject = CreateSubject(ClusterConnectionMode.Sharded); +#pragma warning restore CS0618 // Type or member is obsolete + + subject.Initialize(); + + var endPoint1 = new DnsEndPoint("localhost", 27017); + var connected1 = ServerDescriptionHelper.Connected(subject.Description.ClusterId, endPoint1); + + subject.SetServerDescriptions(connected1); + + var selector = new DelegateServerSelector((c, s) => s); + + _capturedEvents.Clear(); + + IServer result; + if (async) + { + result = await subject.SelectServerAsync(selector, null, CancellationToken.None); + } + else + { + result = subject.SelectServer(selector, null, CancellationToken.None); + } + + result.Should().NotBeNull(); + result.EndPoint.Should().Be(endPoint1); + Logs.Count(log => log.Category == "MongoDB.ServerSelection" && log.Message.StartsWith("Deprioritization")).Should().Be(0); + + _capturedEvents.Next().Should().BeOfType(); + _capturedEvents.Next().Should().BeOfType(); + _capturedEvents.Any().Should().BeFalse(); + } + + [Theory] + [ParameterAttributeData] + public async void SelectServer_should_return_deprioritized_servers_if_no_other_servers_exist_or_cluster_not_sharded( [Values(false, true)] bool async, - [Values(false, true)] bool IsSharded) + [Values(false, true)] bool isSharded) { #pragma warning disable CS0618 // Type or member is obsolete - StubCluster subject = IsSharded ? CreateSubject(ClusterConnectionMode.Sharded) : CreateSubject(); + StubCluster subject = isSharded ? CreateSubject(ClusterConnectionMode.Sharded) : CreateSubject(); #pragma warning restore CS0618 // Type or member is obsolete subject.Initialize(); @@ -483,6 +521,7 @@ public void SelectServer_should_return_deprioritized_servers_if_no_other_servers var selector = new DelegateServerSelector((c, s) => s); var deprioritizedServers = new List { connected1, connected2 }; + var deprioritizedServersEndpoints = deprioritizedServers.Select(description => description.EndPoint).ToList(); for (int i = 0; i < 15; i++) { @@ -490,7 +529,7 @@ public void SelectServer_should_return_deprioritized_servers_if_no_other_servers IServer result; if (async) { - result = subject.SelectServerAsync(selector, deprioritizedServers, CancellationToken.None).GetAwaiter().GetResult(); + result = await subject.SelectServerAsync(selector, deprioritizedServers, CancellationToken.None); } else { @@ -498,8 +537,6 @@ public void SelectServer_should_return_deprioritized_servers_if_no_other_servers } result.Should().NotBeNull(); - - var deprioritizedServersEndpoints = deprioritizedServers.Select(description => description.EndPoint); deprioritizedServersEndpoints.Should().Contain(result.Description.EndPoint); _capturedEvents.Next().Should().BeOfType(); diff --git a/tests/MongoDB.Driver.Core.Tests/Core/Operations/ReadCommandOperationTests.cs b/tests/MongoDB.Driver.Core.Tests/Core/Operations/ReadCommandOperationTests.cs index e66a2fa67d1..71b9a18e4b4 100644 --- a/tests/MongoDB.Driver.Core.Tests/Core/Operations/ReadCommandOperationTests.cs +++ b/tests/MongoDB.Driver.Core.Tests/Core/Operations/ReadCommandOperationTests.cs @@ -348,8 +348,8 @@ private Mock CreateMockReadBinding(ReadPreference readPreference, var mockSession = new Mock(); mockBinding.SetupGet(b => b.ReadPreference).Returns(readPreference); mockBinding.SetupGet(b => b.Session).Returns(mockSession.Object); - mockBinding.Setup(b => b.GetReadChannelSource(It.IsAny())).Returns(channelSource); - mockBinding.Setup(b => b.GetReadChannelSourceAsync(It.IsAny())).Returns(Task.FromResult(channelSource)); + mockBinding.Setup(b => b.GetReadChannelSource(It.IsAny(), null)).Returns(channelSource); + mockBinding.Setup(b => b.GetReadChannelSourceAsync(It.IsAny(), null)).Returns(Task.FromResult(channelSource)); return mockBinding; } diff --git a/tests/MongoDB.Driver.Core.Tests/Core/Operations/RetryableWriteOperationExecutorTests.cs b/tests/MongoDB.Driver.Core.Tests/Core/Operations/RetryableWriteOperationExecutorTests.cs index 9d7fd2f7f3b..e95092a0681 100644 --- a/tests/MongoDB.Driver.Core.Tests/Core/Operations/RetryableWriteOperationExecutorTests.cs +++ b/tests/MongoDB.Driver.Core.Tests/Core/Operations/RetryableWriteOperationExecutorTests.cs @@ -98,7 +98,7 @@ private IWriteBinding CreateBinding(bool areRetryableWritesSupported, bool hasSe var session = CreateSession(hasSessionId, isInTransaction); var channelSource = CreateChannelSource(areRetryableWritesSupported); mockBinding.SetupGet(m => m.Session).Returns(session); - mockBinding.Setup(m => m.GetWriteChannelSource(CancellationToken.None)).Returns(channelSource); + mockBinding.Setup(m => m.GetWriteChannelSource(CancellationToken.None, null)).Returns(channelSource); return mockBinding.Object; } diff --git a/tests/MongoDB.Driver.Core.Tests/Core/Operations/WriteCommandOperationTests.cs b/tests/MongoDB.Driver.Core.Tests/Core/Operations/WriteCommandOperationTests.cs index 6da9926706f..88135324973 100644 --- a/tests/MongoDB.Driver.Core.Tests/Core/Operations/WriteCommandOperationTests.cs +++ b/tests/MongoDB.Driver.Core.Tests/Core/Operations/WriteCommandOperationTests.cs @@ -233,8 +233,8 @@ private Mock CreateMockWriteBinding(IChannelSourceHandle channelS var mockBinding = new Mock(); var mockSession = new Mock(); mockBinding.SetupGet(b => b.Session).Returns(mockSession.Object); - mockBinding.Setup(b => b.GetWriteChannelSource(It.IsAny())).Returns(channelSource); - mockBinding.Setup(b => b.GetWriteChannelSourceAsync(It.IsAny())).Returns(Task.FromResult(channelSource)); + mockBinding.Setup(b => b.GetWriteChannelSource(It.IsAny(), null)).Returns(channelSource); + mockBinding.Setup(b => b.GetWriteChannelSourceAsync(It.IsAny(), null)).Returns(Task.FromResult(channelSource)); return mockBinding; } From 3e6d403aaae1bf136267eda115fc8ee99c29e6a6 Mon Sep 17 00:00:00 2001 From: adelinowona Date: Tue, 23 Apr 2024 14:59:59 -0400 Subject: [PATCH 10/24] remove unnecessary white space --- .../Core/Bindings/ChannelReadBinding.cs | 4 ++-- .../Core/Bindings/ChannelReadWriteBinding.cs | 12 ++++++------ .../Core/Bindings/ChannelSourceReadWriteBinding.cs | 12 ++++++------ .../Core/Bindings/ReadBindingHandle.cs | 4 ++-- .../Core/Bindings/ReadPreferenceBinding.cs | 4 ++-- .../Core/Bindings/ReadWriteBindingHandle.cs | 12 ++++++------ .../Core/Bindings/SingleServerReadBinding.cs | 4 ++-- .../Core/Bindings/SingleServerReadWriteBinding.cs | 12 ++++++------ .../Core/Bindings/WritableServerBinding.cs | 12 ++++++------ 9 files changed, 38 insertions(+), 38 deletions(-) diff --git a/src/MongoDB.Driver.Core/Core/Bindings/ChannelReadBinding.cs b/src/MongoDB.Driver.Core/Core/Bindings/ChannelReadBinding.cs index ff5699f60c0..b16961a5c7a 100644 --- a/src/MongoDB.Driver.Core/Core/Bindings/ChannelReadBinding.cs +++ b/src/MongoDB.Driver.Core/Core/Bindings/ChannelReadBinding.cs @@ -75,14 +75,14 @@ public void Dispose() } } - /// + /// public IChannelSourceHandle GetReadChannelSource(CancellationToken cancellationToken, IReadOnlyCollection deprioritizedServers = null) { ThrowIfDisposed(); return GetReadChannelSourceHelper(); } - /// + /// public Task GetReadChannelSourceAsync(CancellationToken cancellationToken, IReadOnlyCollection deprioritizedServers = null) { ThrowIfDisposed(); diff --git a/src/MongoDB.Driver.Core/Core/Bindings/ChannelReadWriteBinding.cs b/src/MongoDB.Driver.Core/Core/Bindings/ChannelReadWriteBinding.cs index 29624f77cf4..0bf3e39d2a7 100644 --- a/src/MongoDB.Driver.Core/Core/Bindings/ChannelReadWriteBinding.cs +++ b/src/MongoDB.Driver.Core/Core/Bindings/ChannelReadWriteBinding.cs @@ -72,41 +72,41 @@ public void Dispose() } } - /// + /// public IChannelSourceHandle GetReadChannelSource(CancellationToken cancellationToken, IReadOnlyCollection deprioritizedServers = null) { ThrowIfDisposed(); return GetChannelSourceHelper(); } - /// + /// public Task GetReadChannelSourceAsync(CancellationToken cancellationToken, IReadOnlyCollection deprioritizedServers = null) { ThrowIfDisposed(); return Task.FromResult(GetChannelSourceHelper()); } - /// + /// public IChannelSourceHandle GetWriteChannelSource(CancellationToken cancellationToken, IReadOnlyCollection deprioritizedServers = null) { ThrowIfDisposed(); return GetChannelSourceHelper(); } - /// + /// public IChannelSourceHandle GetWriteChannelSource(IMayUseSecondaryCriteria mayUseSecondary, CancellationToken cancellationToken, IReadOnlyCollection deprioritizedServers = null) { return GetWriteChannelSource(cancellationToken, deprioritizedServers); // ignore mayUseSecondary } - /// + /// public Task GetWriteChannelSourceAsync(CancellationToken cancellationToken, IReadOnlyCollection deprioritizedServers = null) { ThrowIfDisposed(); return Task.FromResult(GetChannelSourceHelper()); } - /// + /// public Task GetWriteChannelSourceAsync(IMayUseSecondaryCriteria mayUseSecondary, CancellationToken cancellationToken, IReadOnlyCollection deprioritizedServers = null) { return GetWriteChannelSourceAsync(cancellationToken, deprioritizedServers); // ignore mayUseSecondary diff --git a/src/MongoDB.Driver.Core/Core/Bindings/ChannelSourceReadWriteBinding.cs b/src/MongoDB.Driver.Core/Core/Bindings/ChannelSourceReadWriteBinding.cs index 6aa976db82a..d01f75cfc71 100644 --- a/src/MongoDB.Driver.Core/Core/Bindings/ChannelSourceReadWriteBinding.cs +++ b/src/MongoDB.Driver.Core/Core/Bindings/ChannelSourceReadWriteBinding.cs @@ -61,41 +61,41 @@ public ICoreSessionHandle Session } // methods - /// + /// public IChannelSourceHandle GetReadChannelSource(CancellationToken cancellationToken, IReadOnlyCollection deprioritizedServers = null) { ThrowIfDisposed(); return GetChannelSourceHelper(); } - /// + /// public Task GetReadChannelSourceAsync(CancellationToken cancellationToken, IReadOnlyCollection deprioritizedServers = null) { ThrowIfDisposed(); return Task.FromResult(GetChannelSourceHelper()); } - /// + /// public IChannelSourceHandle GetWriteChannelSource(CancellationToken cancellationToken, IReadOnlyCollection deprioritizedServers = null) { ThrowIfDisposed(); return GetChannelSourceHelper(); } - /// + /// public IChannelSourceHandle GetWriteChannelSource(IMayUseSecondaryCriteria mayUseSecondary, CancellationToken cancellationToken, IReadOnlyCollection deprioritizedServers = null) { return GetWriteChannelSource(cancellationToken, deprioritizedServers); // ignore mayUseSecondary } - /// + /// public Task GetWriteChannelSourceAsync(CancellationToken cancellationToken, IReadOnlyCollection deprioritizedServers = null) { ThrowIfDisposed(); return Task.FromResult(GetChannelSourceHelper()); } - /// + /// public Task GetWriteChannelSourceAsync(IMayUseSecondaryCriteria mayUseSecondary, CancellationToken cancellationToken, IReadOnlyCollection deprioritizedServers = null) { return GetWriteChannelSourceAsync(cancellationToken, deprioritizedServers); // ignore mayUseSecondary diff --git a/src/MongoDB.Driver.Core/Core/Bindings/ReadBindingHandle.cs b/src/MongoDB.Driver.Core/Core/Bindings/ReadBindingHandle.cs index 8d9e448f5db..53ee61378a8 100644 --- a/src/MongoDB.Driver.Core/Core/Bindings/ReadBindingHandle.cs +++ b/src/MongoDB.Driver.Core/Core/Bindings/ReadBindingHandle.cs @@ -59,14 +59,14 @@ public ICoreSessionHandle Session get { return _reference.Instance.Session; } } - /// + /// public IChannelSourceHandle GetReadChannelSource(CancellationToken cancellationToken, IReadOnlyCollection deprioritizedServers = null) { ThrowIfDisposed(); return _reference.Instance.GetReadChannelSource(cancellationToken, deprioritizedServers); } - /// + /// public Task GetReadChannelSourceAsync(CancellationToken cancellationToken, IReadOnlyCollection deprioritizedServers = null) { ThrowIfDisposed(); diff --git a/src/MongoDB.Driver.Core/Core/Bindings/ReadPreferenceBinding.cs b/src/MongoDB.Driver.Core/Core/Bindings/ReadPreferenceBinding.cs index 26c0868463a..e1a72003a67 100644 --- a/src/MongoDB.Driver.Core/Core/Bindings/ReadPreferenceBinding.cs +++ b/src/MongoDB.Driver.Core/Core/Bindings/ReadPreferenceBinding.cs @@ -65,7 +65,7 @@ public ICoreSessionHandle Session } // methods - /// + /// public IChannelSourceHandle GetReadChannelSource(CancellationToken cancellationToken, IReadOnlyCollection deprioritizedServers = null) { ThrowIfDisposed(); @@ -73,7 +73,7 @@ public IChannelSourceHandle GetReadChannelSource(CancellationToken cancellationT return GetChannelSourceHelper(server); } - /// + /// public async Task GetReadChannelSourceAsync(CancellationToken cancellationToken, IReadOnlyCollection deprioritizedServers = null) { ThrowIfDisposed(); diff --git a/src/MongoDB.Driver.Core/Core/Bindings/ReadWriteBindingHandle.cs b/src/MongoDB.Driver.Core/Core/Bindings/ReadWriteBindingHandle.cs index c43c4ab05c0..73c97d697be 100644 --- a/src/MongoDB.Driver.Core/Core/Bindings/ReadWriteBindingHandle.cs +++ b/src/MongoDB.Driver.Core/Core/Bindings/ReadWriteBindingHandle.cs @@ -59,42 +59,42 @@ public ICoreSessionHandle Session get { return _reference.Instance.Session; } } - /// + /// public IChannelSourceHandle GetReadChannelSource(CancellationToken cancellationToken, IReadOnlyCollection deprioritizedServers = null) { ThrowIfDisposed(); return _reference.Instance.GetReadChannelSource(cancellationToken, deprioritizedServers); } - /// + /// public Task GetReadChannelSourceAsync(CancellationToken cancellationToken, IReadOnlyCollection deprioritizedServers = null) { ThrowIfDisposed(); return _reference.Instance.GetReadChannelSourceAsync(cancellationToken, deprioritizedServers); } - /// + /// public IChannelSourceHandle GetWriteChannelSource(CancellationToken cancellationToken, IReadOnlyCollection deprioritizedServers = null) { ThrowIfDisposed(); return _reference.Instance.GetWriteChannelSource(cancellationToken, deprioritizedServers); } - /// + /// public IChannelSourceHandle GetWriteChannelSource(IMayUseSecondaryCriteria mayUseSecondary, CancellationToken cancellationToken, IReadOnlyCollection deprioritizedServers = null) { ThrowIfDisposed(); return _reference.Instance.GetWriteChannelSource(mayUseSecondary, cancellationToken, deprioritizedServers); } - /// + /// public Task GetWriteChannelSourceAsync(CancellationToken cancellationToken, IReadOnlyCollection deprioritizedServers = null) { ThrowIfDisposed(); return _reference.Instance.GetWriteChannelSourceAsync(cancellationToken, deprioritizedServers); } - /// + /// public Task GetWriteChannelSourceAsync(IMayUseSecondaryCriteria mayUseSecondary, CancellationToken cancellationToken, IReadOnlyCollection deprioritizedServers = null) { ThrowIfDisposed(); diff --git a/src/MongoDB.Driver.Core/Core/Bindings/SingleServerReadBinding.cs b/src/MongoDB.Driver.Core/Core/Bindings/SingleServerReadBinding.cs index 28cb59c095c..e12524c2355 100644 --- a/src/MongoDB.Driver.Core/Core/Bindings/SingleServerReadBinding.cs +++ b/src/MongoDB.Driver.Core/Core/Bindings/SingleServerReadBinding.cs @@ -64,14 +64,14 @@ public ICoreSessionHandle Session } // methods - /// + /// public IChannelSourceHandle GetReadChannelSource(CancellationToken cancellationToken, IReadOnlyCollection deprioritizedServers = null) { ThrowIfDisposed(); return GetChannelSourceHelper(); } - /// + /// public Task GetReadChannelSourceAsync(CancellationToken cancellationToken, IReadOnlyCollection deprioritizedServers = null) { ThrowIfDisposed(); diff --git a/src/MongoDB.Driver.Core/Core/Bindings/SingleServerReadWriteBinding.cs b/src/MongoDB.Driver.Core/Core/Bindings/SingleServerReadWriteBinding.cs index ec849cde1f2..a8d5359f11b 100644 --- a/src/MongoDB.Driver.Core/Core/Bindings/SingleServerReadWriteBinding.cs +++ b/src/MongoDB.Driver.Core/Core/Bindings/SingleServerReadWriteBinding.cs @@ -68,41 +68,41 @@ public void Dispose() } } - /// + /// public IChannelSourceHandle GetReadChannelSource(CancellationToken cancellationToken, IReadOnlyCollection deprioritizedServers = null) { ThrowIfDisposed(); return GetChannelSourceHelper(); } - /// + /// public Task GetReadChannelSourceAsync(CancellationToken cancellationToken, IReadOnlyCollection deprioritizedServers = null) { ThrowIfDisposed(); return Task.FromResult(GetChannelSourceHelper()); } - /// + /// public IChannelSourceHandle GetWriteChannelSource(CancellationToken cancellationToken, IReadOnlyCollection deprioritizedServers = null) { ThrowIfDisposed(); return GetChannelSourceHelper(); } - /// + /// public IChannelSourceHandle GetWriteChannelSource(IMayUseSecondaryCriteria mayUseSecondary, CancellationToken cancellationToken, IReadOnlyCollection deprioritizedServers = null) { return GetWriteChannelSource(cancellationToken, deprioritizedServers); // ignore mayUseSecondary } - /// + /// public Task GetWriteChannelSourceAsync(CancellationToken cancellationToken, IReadOnlyCollection deprioritizedServers = null) { ThrowIfDisposed(); return Task.FromResult(GetChannelSourceHelper()); } - /// + /// public Task GetWriteChannelSourceAsync(IMayUseSecondaryCriteria mayUseSecondary, CancellationToken cancellationToken, IReadOnlyCollection deprioritizedServers = null) { return GetWriteChannelSourceAsync(cancellationToken, deprioritizedServers); // ignore mayUseSecondary diff --git a/src/MongoDB.Driver.Core/Core/Bindings/WritableServerBinding.cs b/src/MongoDB.Driver.Core/Core/Bindings/WritableServerBinding.cs index 52d28a61914..dbcc47aa3ba 100644 --- a/src/MongoDB.Driver.Core/Core/Bindings/WritableServerBinding.cs +++ b/src/MongoDB.Driver.Core/Core/Bindings/WritableServerBinding.cs @@ -60,7 +60,7 @@ public ICoreSessionHandle Session } // methods - /// + /// public IChannelSourceHandle GetReadChannelSource(CancellationToken cancellationToken, IReadOnlyCollection deprioritizedServers = null) { ThrowIfDisposed(); @@ -68,7 +68,7 @@ public IChannelSourceHandle GetReadChannelSource(CancellationToken cancellationT return CreateServerChannelSource(server); } - /// + /// public async Task GetReadChannelSourceAsync(CancellationToken cancellationToken, IReadOnlyCollection deprioritizedServers = null) { ThrowIfDisposed(); @@ -76,7 +76,7 @@ public async Task GetReadChannelSourceAsync(CancellationTo return CreateServerChannelSource(server); } - /// + /// public IChannelSourceHandle GetWriteChannelSource(CancellationToken cancellationToken, IReadOnlyCollection deprioritizedServers = null) { ThrowIfDisposed(); @@ -84,7 +84,7 @@ public IChannelSourceHandle GetWriteChannelSource(CancellationToken cancellation return CreateServerChannelSource(server); } - /// + /// public IChannelSourceHandle GetWriteChannelSource(IMayUseSecondaryCriteria mayUseSecondary, CancellationToken cancellationToken, IReadOnlyCollection deprioritizedServers = null) { if (IsSessionPinnedToServer()) @@ -97,7 +97,7 @@ public IChannelSourceHandle GetWriteChannelSource(IMayUseSecondaryCriteria mayUs return CreateServerChannelSource(server); } - /// + /// public async Task GetWriteChannelSourceAsync(CancellationToken cancellationToken, IReadOnlyCollection deprioritizedServers = null) { ThrowIfDisposed(); @@ -105,7 +105,7 @@ public async Task GetWriteChannelSourceAsync(CancellationT return CreateServerChannelSource(server); } - /// + /// public async Task GetWriteChannelSourceAsync(IMayUseSecondaryCriteria mayUseSecondary, CancellationToken cancellationToken, IReadOnlyCollection deprioritizedServers = null) { if (IsSessionPinnedToServer()) From 1e88dc4457e7fae3e4f0dc468a81cc5c7abdae6c Mon Sep 17 00:00:00 2001 From: adelinowona Date: Tue, 23 Apr 2024 15:44:52 -0400 Subject: [PATCH 11/24] Update api docs and remove overloads --- .../Core/Bindings/IBinding.cs | 12 ++++----- .../Core/Bindings/WritableServerBinding.cs | 4 +-- .../Core/Clusters/Cluster.cs | 14 ++-------- .../Core/Clusters/ICluster.cs | 26 ++++--------------- .../Core/Clusters/IClusterExtensions.cs | 4 +-- .../Core/Clusters/LoadBalancedCluster.cs | 12 ++------- .../Bindings/CoreServerSessionPoolTests.cs | 6 ++--- .../Bindings/ReadPreferenceBindingTests.cs | 12 ++++----- .../Bindings/WritableServerBindingTests.cs | 24 ++++++++--------- .../Core/Clusters/ClusterTests.cs | 12 ++++----- .../Encryption/ClientEncryptionTests.cs | 8 +++--- 11 files changed, 49 insertions(+), 85 deletions(-) diff --git a/src/MongoDB.Driver.Core/Core/Bindings/IBinding.cs b/src/MongoDB.Driver.Core/Core/Bindings/IBinding.cs index 1f6106af757..d25f7625e88 100644 --- a/src/MongoDB.Driver.Core/Core/Bindings/IBinding.cs +++ b/src/MongoDB.Driver.Core/Core/Bindings/IBinding.cs @@ -50,7 +50,7 @@ public interface IReadBinding : IBinding ReadPreference ReadPreference { get; } /// - /// Gets a channel source for read operations while deprioritizing servers in the provided collection. + /// Gets a channel source for read operations and takes an optional collection of servers for deprioritization. /// /// The cancellation token. /// The deprioritized servers. @@ -58,7 +58,7 @@ public interface IReadBinding : IBinding IChannelSourceHandle GetReadChannelSource(CancellationToken cancellationToken, IReadOnlyCollection deprioritizedServers = null); /// - /// Gets a channel source for read operations while deprioritizing servers in the provided collection. + /// Gets a channel source for read operations and takes an optional collection of servers for deprioritization. /// /// The cancellation token. /// The deprioritized servers. @@ -72,7 +72,7 @@ public interface IReadBinding : IBinding public interface IWriteBinding : IBinding { /// - /// Gets a channel source for write operations while deprioritizing servers in the provided collection. + /// Gets a channel source for write operations and takes an optional collection of servers for deprioritization. /// /// The cancellation token. /// The deprioritized servers. @@ -80,7 +80,7 @@ public interface IWriteBinding : IBinding IChannelSourceHandle GetWriteChannelSource(CancellationToken cancellationToken, IReadOnlyCollection deprioritizedServers = null); /// - /// Gets a channel source for write operations that may use a secondary and deprioritizes servers in the provided collection. + /// Gets a channel source for write operations that may use a secondary and takes an optional collection of servers for deprioritization. /// /// The may use secondary criteria. /// The cancellation token. @@ -89,7 +89,7 @@ public interface IWriteBinding : IBinding IChannelSourceHandle GetWriteChannelSource(IMayUseSecondaryCriteria mayUseSecondary, CancellationToken cancellationToken, IReadOnlyCollection deprioritizedServers = null); /// - /// Gets a channel source for write operations while deprioritizing servers in the provided collection. + /// Gets a channel source for write operations and takes an optional collection of servers for deprioritization. /// /// The cancellation token. /// The deprioritized servers. @@ -97,7 +97,7 @@ public interface IWriteBinding : IBinding Task GetWriteChannelSourceAsync(CancellationToken cancellationToken, IReadOnlyCollection deprioritizedServers = null); /// - /// Gets a channel source for write operations that may use a secondary and deprioritizes servers in the provided collection. + /// Gets a channel source for write operations that may use a secondary and takes an optional collection of servers for deprioritization. /// /// The may use secondary criteria. /// The cancellation token. diff --git a/src/MongoDB.Driver.Core/Core/Bindings/WritableServerBinding.cs b/src/MongoDB.Driver.Core/Core/Bindings/WritableServerBinding.cs index dbcc47aa3ba..7f2eb00ffad 100644 --- a/src/MongoDB.Driver.Core/Core/Bindings/WritableServerBinding.cs +++ b/src/MongoDB.Driver.Core/Core/Bindings/WritableServerBinding.cs @@ -93,7 +93,7 @@ public IChannelSourceHandle GetWriteChannelSource(IMayUseSecondaryCriteria mayUs } var selector = new WritableServerSelector(mayUseSecondary); - var server = _cluster.SelectServer(selector, deprioritizedServers, cancellationToken); + var server = _cluster.SelectServer(selector, cancellationToken, deprioritizedServers); return CreateServerChannelSource(server); } @@ -114,7 +114,7 @@ public async Task GetWriteChannelSourceAsync(IMayUseSecond } var selector = new WritableServerSelector(mayUseSecondary); - var server = await _cluster.SelectServerAsync(selector, deprioritizedServers, cancellationToken).ConfigureAwait(false); + var server = await _cluster.SelectServerAsync(selector, cancellationToken, deprioritizedServers).ConfigureAwait(false); return CreateServerChannelSource(server); } diff --git a/src/MongoDB.Driver.Core/Core/Clusters/Cluster.cs b/src/MongoDB.Driver.Core/Core/Clusters/Cluster.cs index ec6f008c797..8dcbda60e95 100644 --- a/src/MongoDB.Driver.Core/Core/Clusters/Cluster.cs +++ b/src/MongoDB.Driver.Core/Core/Clusters/Cluster.cs @@ -280,17 +280,7 @@ protected void OnDescriptionChanged(ClusterDescription oldDescription, ClusterDe DescriptionChanged?.Invoke(this, new ClusterDescriptionChangedEventArgs(oldDescription, newDescription)); } - public IServer SelectServer(IServerSelector selector, CancellationToken cancellationToken) - { - return SelectServer(selector, null, cancellationToken); - } - - public Task SelectServerAsync(IServerSelector selector, CancellationToken cancellationToken) - { - return SelectServerAsync(selector, null, cancellationToken); - } - - public IServer SelectServer(IServerSelector selector, IReadOnlyCollection deprioritizedServers, CancellationToken cancellationToken) + public IServer SelectServer(IServerSelector selector, CancellationToken cancellationToken, IReadOnlyCollection deprioritizedServers = null) { ThrowIfDisposedOrNotOpen(); Ensure.IsNotNull(selector, nameof(selector)); @@ -319,7 +309,7 @@ public IServer SelectServer(IServerSelector selector, IReadOnlyCollection SelectServerAsync(IServerSelector selector, IReadOnlyCollection deprioritizedServers, CancellationToken cancellationToken) + public async Task SelectServerAsync(IServerSelector selector, CancellationToken cancellationToken, IReadOnlyCollection deprioritizedServers = null) { ThrowIfDisposedOrNotOpen(); Ensure.IsNotNull(selector, nameof(selector)); diff --git a/src/MongoDB.Driver.Core/Core/Clusters/ICluster.cs b/src/MongoDB.Driver.Core/Core/Clusters/ICluster.cs index 47fcd1d4443..a56e836b9a9 100644 --- a/src/MongoDB.Driver.Core/Core/Clusters/ICluster.cs +++ b/src/MongoDB.Driver.Core/Core/Clusters/ICluster.cs @@ -82,38 +82,22 @@ public interface ICluster : IDisposable void Initialize(); /// - /// Selects a server from the cluster. + /// Selects a server from the cluster and takes an optional collection of servers for deprioritization. /// /// The server selector. /// The cancellation token. - /// The selected server. - IServer SelectServer(IServerSelector selector, CancellationToken cancellationToken); - - /// - /// Selects a server from the cluster. - /// - /// The server selector. - /// The cancellation token. - /// A Task representing the operation. The result of the Task is the selected server. - Task SelectServerAsync(IServerSelector selector, CancellationToken cancellationToken); - - /// - /// Selects a server from the cluster while prioritizing servers not found in the provided collection of deprioritized servers. - /// - /// The server selector. /// The deprioritized Servers. - /// The cancellation token. /// The selected server. - IServer SelectServer(IServerSelector selector, IReadOnlyCollection deprioritizedServers, CancellationToken cancellationToken); + IServer SelectServer(IServerSelector selector, CancellationToken cancellationToken, IReadOnlyCollection deprioritizedServers = null); /// - /// Selects a server from the cluster while prioritizing servers not found in the provided collection of deprioritized servers. + /// Selects a server from the cluster and takes an optional collection of servers for deprioritization. /// /// The server selector. - /// The deprioritized Servers. /// The cancellation token. + /// The deprioritized Servers. /// A Task representing the operation. The result of the Task is the selected server. - Task SelectServerAsync(IServerSelector selector, IReadOnlyCollection deprioritizedServers, CancellationToken cancellationToken); + Task SelectServerAsync(IServerSelector selector, CancellationToken cancellationToken, IReadOnlyCollection deprioritizedServers = null); /// /// Starts a session. diff --git a/src/MongoDB.Driver.Core/Core/Clusters/IClusterExtensions.cs b/src/MongoDB.Driver.Core/Core/Clusters/IClusterExtensions.cs index fea76186a7c..f2dda935afc 100644 --- a/src/MongoDB.Driver.Core/Core/Clusters/IClusterExtensions.cs +++ b/src/MongoDB.Driver.Core/Core/Clusters/IClusterExtensions.cs @@ -42,7 +42,7 @@ public static IServer SelectServerAndPinIfNeeded( // Server selection also updates the cluster type, allowing us to to determine if the server // should be pinned. - var server = cluster.SelectServer(selector, deprioritizedServers, cancellationToken); + var server = cluster.SelectServer(selector, cancellationToken, deprioritizedServers); PinServerIfNeeded(cluster, session, server); return server; } @@ -62,7 +62,7 @@ public static async Task SelectServerAndPinIfNeededAsync( // Server selection also updates the cluster type, allowing us to to determine if the server // should be pinned. - var server = await cluster.SelectServerAsync(selector, deprioritizedServers, cancellationToken).ConfigureAwait(false); + var server = await cluster.SelectServerAsync(selector, cancellationToken, deprioritizedServers).ConfigureAwait(false); PinServerIfNeeded(cluster, session, server); return server; diff --git a/src/MongoDB.Driver.Core/Core/Clusters/LoadBalancedCluster.cs b/src/MongoDB.Driver.Core/Core/Clusters/LoadBalancedCluster.cs index af4e8eb9a50..78876deb6eb 100644 --- a/src/MongoDB.Driver.Core/Core/Clusters/LoadBalancedCluster.cs +++ b/src/MongoDB.Driver.Core/Core/Clusters/LoadBalancedCluster.cs @@ -191,7 +191,7 @@ public void Initialize() } } - public IServer SelectServer(IServerSelector selector, CancellationToken cancellationToken) + public IServer SelectServer(IServerSelector selector, CancellationToken cancellationToken, IReadOnlyCollection deprioritizedServers = null) { ThrowIfDisposed(); @@ -223,7 +223,7 @@ public IServer SelectServer(IServerSelector selector, CancellationToken cancella throw new InvalidOperationException("The server must be created before usage."); // should not be reached } - public async Task SelectServerAsync(IServerSelector selector, CancellationToken cancellationToken) + public async Task SelectServerAsync(IServerSelector selector, CancellationToken cancellationToken, IReadOnlyCollection deprioritizedServers = null) { ThrowIfDisposed(); @@ -256,14 +256,6 @@ public async Task SelectServerAsync(IServerSelector selector, Cancellat throw new InvalidOperationException("The server must be created before usage."); // should not be reached } - public IServer SelectServer(IServerSelector selector, IReadOnlyCollection deprioritizedServers, - CancellationToken cancellationToken) => - throw new NotImplementedException(); - - public Task SelectServerAsync(IServerSelector selector, IReadOnlyCollection deprioritizedServers, - CancellationToken cancellationToken) => - throw new NotImplementedException(); - public ICoreSessionHandle StartSession(CoreSessionOptions options = null) { ThrowIfDisposed(); diff --git a/tests/MongoDB.Driver.Core.Tests/Core/Bindings/CoreServerSessionPoolTests.cs b/tests/MongoDB.Driver.Core.Tests/Core/Bindings/CoreServerSessionPoolTests.cs index 0996d933304..1e4be47551e 100644 --- a/tests/MongoDB.Driver.Core.Tests/Core/Bindings/CoreServerSessionPoolTests.cs +++ b/tests/MongoDB.Driver.Core.Tests/Core/Bindings/CoreServerSessionPoolTests.cs @@ -307,10 +307,8 @@ public TestCluster(ClusterType clusterType) public ICoreServerSession AcquireServerSession() => throw new NotImplementedException(); public void Dispose() => throw new NotImplementedException(); public void Initialize() => DescriptionChanged?.Invoke(this, new ClusterDescriptionChangedEventArgs(Description, Description)); - public IServer SelectServer(IServerSelector selector, CancellationToken cancellationToken) => throw new NotImplementedException(); - public Task SelectServerAsync(IServerSelector selector, CancellationToken cancellationToken) => throw new NotImplementedException(); - public IServer SelectServer(IServerSelector selector, IReadOnlyCollection deprioritizedServers, CancellationToken cancellationToken) => throw new NotImplementedException(); - public Task SelectServerAsync(IServerSelector selector, IReadOnlyCollection deprioritizedServers, CancellationToken cancellationToken) => throw new NotImplementedException(); + public IServer SelectServer(IServerSelector selector, CancellationToken cancellationToken, IReadOnlyCollection deprioritizedServers = null) => throw new NotImplementedException(); + public Task SelectServerAsync(IServerSelector selector, CancellationToken cancellationToken, IReadOnlyCollection deprioritizedServers = null) => throw new NotImplementedException(); public ICoreSessionHandle StartSession(CoreSessionOptions options = null) => throw new NotImplementedException(); } } diff --git a/tests/MongoDB.Driver.Core.Tests/Core/Bindings/ReadPreferenceBindingTests.cs b/tests/MongoDB.Driver.Core.Tests/Core/Bindings/ReadPreferenceBindingTests.cs index b523b942c83..38f79f0eee0 100644 --- a/tests/MongoDB.Driver.Core.Tests/Core/Bindings/ReadPreferenceBindingTests.cs +++ b/tests/MongoDB.Driver.Core.Tests/Core/Bindings/ReadPreferenceBindingTests.cs @@ -119,19 +119,19 @@ public void GetReadChannelSource_should_use_a_read_preference_server_selector_to if (async) { - _mockCluster.Setup(c => c.SelectServerAsync(It.IsAny(), null, CancellationToken.None)).Returns(Task.FromResult(selectedServer)); + _mockCluster.Setup(c => c.SelectServerAsync(It.IsAny(), CancellationToken.None, null)).Returns(Task.FromResult(selectedServer)); subject.GetReadChannelSourceAsync(CancellationToken.None).GetAwaiter().GetResult(); - _mockCluster.Verify(c => c.SelectServerAsync(It.IsAny(), null, CancellationToken.None), Times.Once); + _mockCluster.Verify(c => c.SelectServerAsync(It.IsAny(), CancellationToken.None, null), Times.Once); } else { - _mockCluster.Setup(c => c.SelectServer(It.IsAny(), null, CancellationToken.None)).Returns(selectedServer); + _mockCluster.Setup(c => c.SelectServer(It.IsAny(), CancellationToken.None, null)).Returns(selectedServer); subject.GetReadChannelSource(CancellationToken.None); - _mockCluster.Verify(c => c.SelectServer(It.IsAny(), null, CancellationToken.None), Times.Once); + _mockCluster.Verify(c => c.SelectServer(It.IsAny(), CancellationToken.None, null), Times.Once); } } @@ -146,8 +146,8 @@ public void GetReadChannelSource_should_fork_the_session( var cancellationToken = cancellationTokenSource.Token; var selectedServer = new Mock().Object; - _mockCluster.Setup(m => m.SelectServer(It.IsAny(), null, cancellationToken)).Returns(selectedServer); - _mockCluster.Setup(m => m.SelectServerAsync(It.IsAny(), null, cancellationToken)).Returns(Task.FromResult(selectedServer)); + _mockCluster.Setup(m => m.SelectServer(It.IsAny(), cancellationToken, null)).Returns(selectedServer); + _mockCluster.Setup(m => m.SelectServerAsync(It.IsAny(), cancellationToken, null)).Returns(Task.FromResult(selectedServer)); var forkedSession = new Mock().Object; mockSession.Setup(m => m.Fork()).Returns(forkedSession); diff --git a/tests/MongoDB.Driver.Core.Tests/Core/Bindings/WritableServerBindingTests.cs b/tests/MongoDB.Driver.Core.Tests/Core/Bindings/WritableServerBindingTests.cs index c71e283091b..1f9ba269925 100644 --- a/tests/MongoDB.Driver.Core.Tests/Core/Bindings/WritableServerBindingTests.cs +++ b/tests/MongoDB.Driver.Core.Tests/Core/Bindings/WritableServerBindingTests.cs @@ -123,19 +123,19 @@ public void GetReadChannelSource_should_use_a_writable_server_selector_to_select if (async) { - _mockCluster.Setup(c => c.SelectServerAsync(It.IsAny(), null, CancellationToken.None)).Returns(Task.FromResult(selectedServer)); + _mockCluster.Setup(c => c.SelectServerAsync(It.IsAny(), CancellationToken.None, null)).Returns(Task.FromResult(selectedServer)); subject.GetReadChannelSourceAsync(CancellationToken.None).GetAwaiter().GetResult(); - _mockCluster.Verify(c => c.SelectServerAsync(It.IsAny(), null, CancellationToken.None), Times.Once); + _mockCluster.Verify(c => c.SelectServerAsync(It.IsAny(), CancellationToken.None, null), Times.Once); } else { - _mockCluster.Setup(c => c.SelectServer(It.IsAny(), null, CancellationToken.None)).Returns(selectedServer); + _mockCluster.Setup(c => c.SelectServer(It.IsAny(), CancellationToken.None, null)).Returns(selectedServer); subject.GetReadChannelSource(CancellationToken.None); - _mockCluster.Verify(c => c.SelectServer(It.IsAny(), null, CancellationToken.None), Times.Once); + _mockCluster.Verify(c => c.SelectServer(It.IsAny(), CancellationToken.None, null), Times.Once); } } @@ -184,19 +184,19 @@ public void GetWriteChannelSourceAsync_should_use_a_writable_server_selector_to_ if (async) { - _mockCluster.Setup(c => c.SelectServerAsync(It.IsAny(), null, CancellationToken.None)).Returns(Task.FromResult(selectedServer)); + _mockCluster.Setup(c => c.SelectServerAsync(It.IsAny(), CancellationToken.None, null)).Returns(Task.FromResult(selectedServer)); subject.GetWriteChannelSourceAsync(CancellationToken.None).GetAwaiter().GetResult(); - _mockCluster.Verify(c => c.SelectServerAsync(It.IsAny(), null, CancellationToken.None), Times.Once); + _mockCluster.Verify(c => c.SelectServerAsync(It.IsAny(), CancellationToken.None, null), Times.Once); } else { - _mockCluster.Setup(c => c.SelectServer(It.IsAny(), null, CancellationToken.None)).Returns(selectedServer); + _mockCluster.Setup(c => c.SelectServer(It.IsAny(), CancellationToken.None, null)).Returns(selectedServer); subject.GetWriteChannelSource(CancellationToken.None); - _mockCluster.Verify(c => c.SelectServer(It.IsAny(), null, CancellationToken.None), Times.Once); + _mockCluster.Verify(c => c.SelectServer(It.IsAny(), CancellationToken.None, null), Times.Once); } } @@ -228,19 +228,19 @@ public void GetWriteChannelSource_with_mayUseSecondary_should_pass_mayUseSeconda if (async) { - _mockCluster.Setup(c => c.SelectServerAsync(It.IsAny(), null, CancellationToken.None)).Returns(Task.FromResult(selectedServer)); + _mockCluster.Setup(c => c.SelectServerAsync(It.IsAny(), CancellationToken.None, null)).Returns(Task.FromResult(selectedServer)); subject.GetWriteChannelSourceAsync(mayUseSecondary, CancellationToken.None).GetAwaiter().GetResult(); - _mockCluster.Verify(c => c.SelectServerAsync(It.Is(s => s.MayUseSecondary == mayUseSecondary), null, CancellationToken.None), Times.Once); + _mockCluster.Verify(c => c.SelectServerAsync(It.Is(s => s.MayUseSecondary == mayUseSecondary), CancellationToken.None, null), Times.Once); } else { - _mockCluster.Setup(c => c.SelectServer(It.IsAny(), null, CancellationToken.None)).Returns(selectedServer); + _mockCluster.Setup(c => c.SelectServer(It.IsAny(), CancellationToken.None, null)).Returns(selectedServer); subject.GetWriteChannelSource(mayUseSecondary, CancellationToken.None); - _mockCluster.Verify(c => c.SelectServer(It.Is(s => s.MayUseSecondary == mayUseSecondary), null, CancellationToken.None), Times.Once); + _mockCluster.Verify(c => c.SelectServer(It.Is(s => s.MayUseSecondary == mayUseSecondary), CancellationToken.None, null), Times.Once); } } diff --git a/tests/MongoDB.Driver.Core.Tests/Core/Clusters/ClusterTests.cs b/tests/MongoDB.Driver.Core.Tests/Core/Clusters/ClusterTests.cs index ce0d71c8f96..29abf314463 100644 --- a/tests/MongoDB.Driver.Core.Tests/Core/Clusters/ClusterTests.cs +++ b/tests/MongoDB.Driver.Core.Tests/Core/Clusters/ClusterTests.cs @@ -445,11 +445,11 @@ public async void SelectServer_should_ignore_deprioritized_servers_if_cluster_is IServer result; if (async) { - result = await subject.SelectServerAsync(selector, deprioritizedServers, CancellationToken.None); + result = await subject.SelectServerAsync(selector, CancellationToken.None, deprioritizedServers); } else { - result = subject.SelectServer(selector, deprioritizedServers, CancellationToken.None); + result = subject.SelectServer(selector, CancellationToken.None, deprioritizedServers); } result.Should().NotBeNull(); @@ -484,11 +484,11 @@ public async void SelectServer_should_not_deprioritize_if_there_no_servers_to_de IServer result; if (async) { - result = await subject.SelectServerAsync(selector, null, CancellationToken.None); + result = await subject.SelectServerAsync(selector, CancellationToken.None); } else { - result = subject.SelectServer(selector, null, CancellationToken.None); + result = subject.SelectServer(selector, CancellationToken.None); } result.Should().NotBeNull(); @@ -529,11 +529,11 @@ public async void SelectServer_should_return_deprioritized_servers_if_no_other_s IServer result; if (async) { - result = await subject.SelectServerAsync(selector, deprioritizedServers, CancellationToken.None); + result = await subject.SelectServerAsync(selector, CancellationToken.None, deprioritizedServers); } else { - result = subject.SelectServer(selector, deprioritizedServers, CancellationToken.None); + result = subject.SelectServer(selector, CancellationToken.None, deprioritizedServers); } result.Should().NotBeNull(); diff --git a/tests/MongoDB.Driver.Tests/Encryption/ClientEncryptionTests.cs b/tests/MongoDB.Driver.Tests/Encryption/ClientEncryptionTests.cs index a5456c9952c..5eee6c743ff 100644 --- a/tests/MongoDB.Driver.Tests/Encryption/ClientEncryptionTests.cs +++ b/tests/MongoDB.Driver.Tests/Encryption/ClientEncryptionTests.cs @@ -140,10 +140,10 @@ public async Task CreateEncryptedCollection_should_handle_generated_key_when_sec mockServer.Setup(s => s.GetChannelAsync(It.IsAny())).ReturnsAsync(channel); mockCluster - .Setup(m => m.SelectServer(It.IsAny(), null, It.IsAny())) + .Setup(m => m.SelectServer(It.IsAny(), It.IsAny(), null)) .Returns(mockServer.Object); mockCluster - .Setup(m => m.SelectServerAsync(It.IsAny(), null, It.IsAny())) + .Setup(m => m.SelectServerAsync(It.IsAny(), It.IsAny(), null)) .ReturnsAsync(mockServer.Object); var database = Mock.Of(d => @@ -229,10 +229,10 @@ public async Task CreateEncryptedCollection_should_handle_various_encryptedField mockServer.Setup(s => s.GetChannelAsync(It.IsAny())).ReturnsAsync(channel); mockCluster - .Setup(m => m.SelectServer(It.IsAny(), null, It.IsAny())) + .Setup(m => m.SelectServer(It.IsAny(), It.IsAny(), null)) .Returns(mockServer.Object); mockCluster - .Setup(m => m.SelectServerAsync(It.IsAny(), null, It.IsAny())) + .Setup(m => m.SelectServerAsync(It.IsAny(), It.IsAny(), null)) .ReturnsAsync(mockServer.Object); var database = Mock.Of(d => From 73947267032c076d0520ee12e9570c45c7b515a4 Mon Sep 17 00:00:00 2001 From: adelinowona Date: Mon, 29 Apr 2024 18:47:08 -0400 Subject: [PATCH 12/24] Revert "Update api docs and remove overloads" This reverts commit 1e88dc4457e7fae3e4f0dc468a81cc5c7abdae6c. --- .../Core/Bindings/IBinding.cs | 12 ++++----- .../Core/Bindings/WritableServerBinding.cs | 4 +-- .../Core/Clusters/Cluster.cs | 14 ++++++++-- .../Core/Clusters/ICluster.cs | 26 +++++++++++++++---- .../Core/Clusters/IClusterExtensions.cs | 4 +-- .../Core/Clusters/LoadBalancedCluster.cs | 12 +++++++-- .../Bindings/CoreServerSessionPoolTests.cs | 6 +++-- .../Bindings/ReadPreferenceBindingTests.cs | 12 ++++----- .../Bindings/WritableServerBindingTests.cs | 24 ++++++++--------- .../Core/Clusters/ClusterTests.cs | 12 ++++----- .../Encryption/ClientEncryptionTests.cs | 8 +++--- 11 files changed, 85 insertions(+), 49 deletions(-) diff --git a/src/MongoDB.Driver.Core/Core/Bindings/IBinding.cs b/src/MongoDB.Driver.Core/Core/Bindings/IBinding.cs index d25f7625e88..1f6106af757 100644 --- a/src/MongoDB.Driver.Core/Core/Bindings/IBinding.cs +++ b/src/MongoDB.Driver.Core/Core/Bindings/IBinding.cs @@ -50,7 +50,7 @@ public interface IReadBinding : IBinding ReadPreference ReadPreference { get; } /// - /// Gets a channel source for read operations and takes an optional collection of servers for deprioritization. + /// Gets a channel source for read operations while deprioritizing servers in the provided collection. /// /// The cancellation token. /// The deprioritized servers. @@ -58,7 +58,7 @@ public interface IReadBinding : IBinding IChannelSourceHandle GetReadChannelSource(CancellationToken cancellationToken, IReadOnlyCollection deprioritizedServers = null); /// - /// Gets a channel source for read operations and takes an optional collection of servers for deprioritization. + /// Gets a channel source for read operations while deprioritizing servers in the provided collection. /// /// The cancellation token. /// The deprioritized servers. @@ -72,7 +72,7 @@ public interface IReadBinding : IBinding public interface IWriteBinding : IBinding { /// - /// Gets a channel source for write operations and takes an optional collection of servers for deprioritization. + /// Gets a channel source for write operations while deprioritizing servers in the provided collection. /// /// The cancellation token. /// The deprioritized servers. @@ -80,7 +80,7 @@ public interface IWriteBinding : IBinding IChannelSourceHandle GetWriteChannelSource(CancellationToken cancellationToken, IReadOnlyCollection deprioritizedServers = null); /// - /// Gets a channel source for write operations that may use a secondary and takes an optional collection of servers for deprioritization. + /// Gets a channel source for write operations that may use a secondary and deprioritizes servers in the provided collection. /// /// The may use secondary criteria. /// The cancellation token. @@ -89,7 +89,7 @@ public interface IWriteBinding : IBinding IChannelSourceHandle GetWriteChannelSource(IMayUseSecondaryCriteria mayUseSecondary, CancellationToken cancellationToken, IReadOnlyCollection deprioritizedServers = null); /// - /// Gets a channel source for write operations and takes an optional collection of servers for deprioritization. + /// Gets a channel source for write operations while deprioritizing servers in the provided collection. /// /// The cancellation token. /// The deprioritized servers. @@ -97,7 +97,7 @@ public interface IWriteBinding : IBinding Task GetWriteChannelSourceAsync(CancellationToken cancellationToken, IReadOnlyCollection deprioritizedServers = null); /// - /// Gets a channel source for write operations that may use a secondary and takes an optional collection of servers for deprioritization. + /// Gets a channel source for write operations that may use a secondary and deprioritizes servers in the provided collection. /// /// The may use secondary criteria. /// The cancellation token. diff --git a/src/MongoDB.Driver.Core/Core/Bindings/WritableServerBinding.cs b/src/MongoDB.Driver.Core/Core/Bindings/WritableServerBinding.cs index 7f2eb00ffad..dbcc47aa3ba 100644 --- a/src/MongoDB.Driver.Core/Core/Bindings/WritableServerBinding.cs +++ b/src/MongoDB.Driver.Core/Core/Bindings/WritableServerBinding.cs @@ -93,7 +93,7 @@ public IChannelSourceHandle GetWriteChannelSource(IMayUseSecondaryCriteria mayUs } var selector = new WritableServerSelector(mayUseSecondary); - var server = _cluster.SelectServer(selector, cancellationToken, deprioritizedServers); + var server = _cluster.SelectServer(selector, deprioritizedServers, cancellationToken); return CreateServerChannelSource(server); } @@ -114,7 +114,7 @@ public async Task GetWriteChannelSourceAsync(IMayUseSecond } var selector = new WritableServerSelector(mayUseSecondary); - var server = await _cluster.SelectServerAsync(selector, cancellationToken, deprioritizedServers).ConfigureAwait(false); + var server = await _cluster.SelectServerAsync(selector, deprioritizedServers, cancellationToken).ConfigureAwait(false); return CreateServerChannelSource(server); } diff --git a/src/MongoDB.Driver.Core/Core/Clusters/Cluster.cs b/src/MongoDB.Driver.Core/Core/Clusters/Cluster.cs index 8dcbda60e95..ec6f008c797 100644 --- a/src/MongoDB.Driver.Core/Core/Clusters/Cluster.cs +++ b/src/MongoDB.Driver.Core/Core/Clusters/Cluster.cs @@ -280,7 +280,17 @@ protected void OnDescriptionChanged(ClusterDescription oldDescription, ClusterDe DescriptionChanged?.Invoke(this, new ClusterDescriptionChangedEventArgs(oldDescription, newDescription)); } - public IServer SelectServer(IServerSelector selector, CancellationToken cancellationToken, IReadOnlyCollection deprioritizedServers = null) + public IServer SelectServer(IServerSelector selector, CancellationToken cancellationToken) + { + return SelectServer(selector, null, cancellationToken); + } + + public Task SelectServerAsync(IServerSelector selector, CancellationToken cancellationToken) + { + return SelectServerAsync(selector, null, cancellationToken); + } + + public IServer SelectServer(IServerSelector selector, IReadOnlyCollection deprioritizedServers, CancellationToken cancellationToken) { ThrowIfDisposedOrNotOpen(); Ensure.IsNotNull(selector, nameof(selector)); @@ -309,7 +319,7 @@ public IServer SelectServer(IServerSelector selector, CancellationToken cancella } } - public async Task SelectServerAsync(IServerSelector selector, CancellationToken cancellationToken, IReadOnlyCollection deprioritizedServers = null) + public async Task SelectServerAsync(IServerSelector selector, IReadOnlyCollection deprioritizedServers, CancellationToken cancellationToken) { ThrowIfDisposedOrNotOpen(); Ensure.IsNotNull(selector, nameof(selector)); diff --git a/src/MongoDB.Driver.Core/Core/Clusters/ICluster.cs b/src/MongoDB.Driver.Core/Core/Clusters/ICluster.cs index a56e836b9a9..47fcd1d4443 100644 --- a/src/MongoDB.Driver.Core/Core/Clusters/ICluster.cs +++ b/src/MongoDB.Driver.Core/Core/Clusters/ICluster.cs @@ -82,22 +82,38 @@ public interface ICluster : IDisposable void Initialize(); /// - /// Selects a server from the cluster and takes an optional collection of servers for deprioritization. + /// Selects a server from the cluster. /// /// The server selector. /// The cancellation token. - /// The deprioritized Servers. /// The selected server. - IServer SelectServer(IServerSelector selector, CancellationToken cancellationToken, IReadOnlyCollection deprioritizedServers = null); + IServer SelectServer(IServerSelector selector, CancellationToken cancellationToken); + + /// + /// Selects a server from the cluster. + /// + /// The server selector. + /// The cancellation token. + /// A Task representing the operation. The result of the Task is the selected server. + Task SelectServerAsync(IServerSelector selector, CancellationToken cancellationToken); /// - /// Selects a server from the cluster and takes an optional collection of servers for deprioritization. + /// Selects a server from the cluster while prioritizing servers not found in the provided collection of deprioritized servers. /// /// The server selector. + /// The deprioritized Servers. /// The cancellation token. + /// The selected server. + IServer SelectServer(IServerSelector selector, IReadOnlyCollection deprioritizedServers, CancellationToken cancellationToken); + + /// + /// Selects a server from the cluster while prioritizing servers not found in the provided collection of deprioritized servers. + /// + /// The server selector. /// The deprioritized Servers. + /// The cancellation token. /// A Task representing the operation. The result of the Task is the selected server. - Task SelectServerAsync(IServerSelector selector, CancellationToken cancellationToken, IReadOnlyCollection deprioritizedServers = null); + Task SelectServerAsync(IServerSelector selector, IReadOnlyCollection deprioritizedServers, CancellationToken cancellationToken); /// /// Starts a session. diff --git a/src/MongoDB.Driver.Core/Core/Clusters/IClusterExtensions.cs b/src/MongoDB.Driver.Core/Core/Clusters/IClusterExtensions.cs index f2dda935afc..fea76186a7c 100644 --- a/src/MongoDB.Driver.Core/Core/Clusters/IClusterExtensions.cs +++ b/src/MongoDB.Driver.Core/Core/Clusters/IClusterExtensions.cs @@ -42,7 +42,7 @@ public static IServer SelectServerAndPinIfNeeded( // Server selection also updates the cluster type, allowing us to to determine if the server // should be pinned. - var server = cluster.SelectServer(selector, cancellationToken, deprioritizedServers); + var server = cluster.SelectServer(selector, deprioritizedServers, cancellationToken); PinServerIfNeeded(cluster, session, server); return server; } @@ -62,7 +62,7 @@ public static async Task SelectServerAndPinIfNeededAsync( // Server selection also updates the cluster type, allowing us to to determine if the server // should be pinned. - var server = await cluster.SelectServerAsync(selector, cancellationToken, deprioritizedServers).ConfigureAwait(false); + var server = await cluster.SelectServerAsync(selector, deprioritizedServers, cancellationToken).ConfigureAwait(false); PinServerIfNeeded(cluster, session, server); return server; diff --git a/src/MongoDB.Driver.Core/Core/Clusters/LoadBalancedCluster.cs b/src/MongoDB.Driver.Core/Core/Clusters/LoadBalancedCluster.cs index 78876deb6eb..af4e8eb9a50 100644 --- a/src/MongoDB.Driver.Core/Core/Clusters/LoadBalancedCluster.cs +++ b/src/MongoDB.Driver.Core/Core/Clusters/LoadBalancedCluster.cs @@ -191,7 +191,7 @@ public void Initialize() } } - public IServer SelectServer(IServerSelector selector, CancellationToken cancellationToken, IReadOnlyCollection deprioritizedServers = null) + public IServer SelectServer(IServerSelector selector, CancellationToken cancellationToken) { ThrowIfDisposed(); @@ -223,7 +223,7 @@ public IServer SelectServer(IServerSelector selector, CancellationToken cancella throw new InvalidOperationException("The server must be created before usage."); // should not be reached } - public async Task SelectServerAsync(IServerSelector selector, CancellationToken cancellationToken, IReadOnlyCollection deprioritizedServers = null) + public async Task SelectServerAsync(IServerSelector selector, CancellationToken cancellationToken) { ThrowIfDisposed(); @@ -256,6 +256,14 @@ public async Task SelectServerAsync(IServerSelector selector, Cancellat throw new InvalidOperationException("The server must be created before usage."); // should not be reached } + public IServer SelectServer(IServerSelector selector, IReadOnlyCollection deprioritizedServers, + CancellationToken cancellationToken) => + throw new NotImplementedException(); + + public Task SelectServerAsync(IServerSelector selector, IReadOnlyCollection deprioritizedServers, + CancellationToken cancellationToken) => + throw new NotImplementedException(); + public ICoreSessionHandle StartSession(CoreSessionOptions options = null) { ThrowIfDisposed(); diff --git a/tests/MongoDB.Driver.Core.Tests/Core/Bindings/CoreServerSessionPoolTests.cs b/tests/MongoDB.Driver.Core.Tests/Core/Bindings/CoreServerSessionPoolTests.cs index 1e4be47551e..0996d933304 100644 --- a/tests/MongoDB.Driver.Core.Tests/Core/Bindings/CoreServerSessionPoolTests.cs +++ b/tests/MongoDB.Driver.Core.Tests/Core/Bindings/CoreServerSessionPoolTests.cs @@ -307,8 +307,10 @@ public TestCluster(ClusterType clusterType) public ICoreServerSession AcquireServerSession() => throw new NotImplementedException(); public void Dispose() => throw new NotImplementedException(); public void Initialize() => DescriptionChanged?.Invoke(this, new ClusterDescriptionChangedEventArgs(Description, Description)); - public IServer SelectServer(IServerSelector selector, CancellationToken cancellationToken, IReadOnlyCollection deprioritizedServers = null) => throw new NotImplementedException(); - public Task SelectServerAsync(IServerSelector selector, CancellationToken cancellationToken, IReadOnlyCollection deprioritizedServers = null) => throw new NotImplementedException(); + public IServer SelectServer(IServerSelector selector, CancellationToken cancellationToken) => throw new NotImplementedException(); + public Task SelectServerAsync(IServerSelector selector, CancellationToken cancellationToken) => throw new NotImplementedException(); + public IServer SelectServer(IServerSelector selector, IReadOnlyCollection deprioritizedServers, CancellationToken cancellationToken) => throw new NotImplementedException(); + public Task SelectServerAsync(IServerSelector selector, IReadOnlyCollection deprioritizedServers, CancellationToken cancellationToken) => throw new NotImplementedException(); public ICoreSessionHandle StartSession(CoreSessionOptions options = null) => throw new NotImplementedException(); } } diff --git a/tests/MongoDB.Driver.Core.Tests/Core/Bindings/ReadPreferenceBindingTests.cs b/tests/MongoDB.Driver.Core.Tests/Core/Bindings/ReadPreferenceBindingTests.cs index 38f79f0eee0..b523b942c83 100644 --- a/tests/MongoDB.Driver.Core.Tests/Core/Bindings/ReadPreferenceBindingTests.cs +++ b/tests/MongoDB.Driver.Core.Tests/Core/Bindings/ReadPreferenceBindingTests.cs @@ -119,19 +119,19 @@ public void GetReadChannelSource_should_use_a_read_preference_server_selector_to if (async) { - _mockCluster.Setup(c => c.SelectServerAsync(It.IsAny(), CancellationToken.None, null)).Returns(Task.FromResult(selectedServer)); + _mockCluster.Setup(c => c.SelectServerAsync(It.IsAny(), null, CancellationToken.None)).Returns(Task.FromResult(selectedServer)); subject.GetReadChannelSourceAsync(CancellationToken.None).GetAwaiter().GetResult(); - _mockCluster.Verify(c => c.SelectServerAsync(It.IsAny(), CancellationToken.None, null), Times.Once); + _mockCluster.Verify(c => c.SelectServerAsync(It.IsAny(), null, CancellationToken.None), Times.Once); } else { - _mockCluster.Setup(c => c.SelectServer(It.IsAny(), CancellationToken.None, null)).Returns(selectedServer); + _mockCluster.Setup(c => c.SelectServer(It.IsAny(), null, CancellationToken.None)).Returns(selectedServer); subject.GetReadChannelSource(CancellationToken.None); - _mockCluster.Verify(c => c.SelectServer(It.IsAny(), CancellationToken.None, null), Times.Once); + _mockCluster.Verify(c => c.SelectServer(It.IsAny(), null, CancellationToken.None), Times.Once); } } @@ -146,8 +146,8 @@ public void GetReadChannelSource_should_fork_the_session( var cancellationToken = cancellationTokenSource.Token; var selectedServer = new Mock().Object; - _mockCluster.Setup(m => m.SelectServer(It.IsAny(), cancellationToken, null)).Returns(selectedServer); - _mockCluster.Setup(m => m.SelectServerAsync(It.IsAny(), cancellationToken, null)).Returns(Task.FromResult(selectedServer)); + _mockCluster.Setup(m => m.SelectServer(It.IsAny(), null, cancellationToken)).Returns(selectedServer); + _mockCluster.Setup(m => m.SelectServerAsync(It.IsAny(), null, cancellationToken)).Returns(Task.FromResult(selectedServer)); var forkedSession = new Mock().Object; mockSession.Setup(m => m.Fork()).Returns(forkedSession); diff --git a/tests/MongoDB.Driver.Core.Tests/Core/Bindings/WritableServerBindingTests.cs b/tests/MongoDB.Driver.Core.Tests/Core/Bindings/WritableServerBindingTests.cs index 1f9ba269925..c71e283091b 100644 --- a/tests/MongoDB.Driver.Core.Tests/Core/Bindings/WritableServerBindingTests.cs +++ b/tests/MongoDB.Driver.Core.Tests/Core/Bindings/WritableServerBindingTests.cs @@ -123,19 +123,19 @@ public void GetReadChannelSource_should_use_a_writable_server_selector_to_select if (async) { - _mockCluster.Setup(c => c.SelectServerAsync(It.IsAny(), CancellationToken.None, null)).Returns(Task.FromResult(selectedServer)); + _mockCluster.Setup(c => c.SelectServerAsync(It.IsAny(), null, CancellationToken.None)).Returns(Task.FromResult(selectedServer)); subject.GetReadChannelSourceAsync(CancellationToken.None).GetAwaiter().GetResult(); - _mockCluster.Verify(c => c.SelectServerAsync(It.IsAny(), CancellationToken.None, null), Times.Once); + _mockCluster.Verify(c => c.SelectServerAsync(It.IsAny(), null, CancellationToken.None), Times.Once); } else { - _mockCluster.Setup(c => c.SelectServer(It.IsAny(), CancellationToken.None, null)).Returns(selectedServer); + _mockCluster.Setup(c => c.SelectServer(It.IsAny(), null, CancellationToken.None)).Returns(selectedServer); subject.GetReadChannelSource(CancellationToken.None); - _mockCluster.Verify(c => c.SelectServer(It.IsAny(), CancellationToken.None, null), Times.Once); + _mockCluster.Verify(c => c.SelectServer(It.IsAny(), null, CancellationToken.None), Times.Once); } } @@ -184,19 +184,19 @@ public void GetWriteChannelSourceAsync_should_use_a_writable_server_selector_to_ if (async) { - _mockCluster.Setup(c => c.SelectServerAsync(It.IsAny(), CancellationToken.None, null)).Returns(Task.FromResult(selectedServer)); + _mockCluster.Setup(c => c.SelectServerAsync(It.IsAny(), null, CancellationToken.None)).Returns(Task.FromResult(selectedServer)); subject.GetWriteChannelSourceAsync(CancellationToken.None).GetAwaiter().GetResult(); - _mockCluster.Verify(c => c.SelectServerAsync(It.IsAny(), CancellationToken.None, null), Times.Once); + _mockCluster.Verify(c => c.SelectServerAsync(It.IsAny(), null, CancellationToken.None), Times.Once); } else { - _mockCluster.Setup(c => c.SelectServer(It.IsAny(), CancellationToken.None, null)).Returns(selectedServer); + _mockCluster.Setup(c => c.SelectServer(It.IsAny(), null, CancellationToken.None)).Returns(selectedServer); subject.GetWriteChannelSource(CancellationToken.None); - _mockCluster.Verify(c => c.SelectServer(It.IsAny(), CancellationToken.None, null), Times.Once); + _mockCluster.Verify(c => c.SelectServer(It.IsAny(), null, CancellationToken.None), Times.Once); } } @@ -228,19 +228,19 @@ public void GetWriteChannelSource_with_mayUseSecondary_should_pass_mayUseSeconda if (async) { - _mockCluster.Setup(c => c.SelectServerAsync(It.IsAny(), CancellationToken.None, null)).Returns(Task.FromResult(selectedServer)); + _mockCluster.Setup(c => c.SelectServerAsync(It.IsAny(), null, CancellationToken.None)).Returns(Task.FromResult(selectedServer)); subject.GetWriteChannelSourceAsync(mayUseSecondary, CancellationToken.None).GetAwaiter().GetResult(); - _mockCluster.Verify(c => c.SelectServerAsync(It.Is(s => s.MayUseSecondary == mayUseSecondary), CancellationToken.None, null), Times.Once); + _mockCluster.Verify(c => c.SelectServerAsync(It.Is(s => s.MayUseSecondary == mayUseSecondary), null, CancellationToken.None), Times.Once); } else { - _mockCluster.Setup(c => c.SelectServer(It.IsAny(), CancellationToken.None, null)).Returns(selectedServer); + _mockCluster.Setup(c => c.SelectServer(It.IsAny(), null, CancellationToken.None)).Returns(selectedServer); subject.GetWriteChannelSource(mayUseSecondary, CancellationToken.None); - _mockCluster.Verify(c => c.SelectServer(It.Is(s => s.MayUseSecondary == mayUseSecondary), CancellationToken.None, null), Times.Once); + _mockCluster.Verify(c => c.SelectServer(It.Is(s => s.MayUseSecondary == mayUseSecondary), null, CancellationToken.None), Times.Once); } } diff --git a/tests/MongoDB.Driver.Core.Tests/Core/Clusters/ClusterTests.cs b/tests/MongoDB.Driver.Core.Tests/Core/Clusters/ClusterTests.cs index 29abf314463..ce0d71c8f96 100644 --- a/tests/MongoDB.Driver.Core.Tests/Core/Clusters/ClusterTests.cs +++ b/tests/MongoDB.Driver.Core.Tests/Core/Clusters/ClusterTests.cs @@ -445,11 +445,11 @@ public async void SelectServer_should_ignore_deprioritized_servers_if_cluster_is IServer result; if (async) { - result = await subject.SelectServerAsync(selector, CancellationToken.None, deprioritizedServers); + result = await subject.SelectServerAsync(selector, deprioritizedServers, CancellationToken.None); } else { - result = subject.SelectServer(selector, CancellationToken.None, deprioritizedServers); + result = subject.SelectServer(selector, deprioritizedServers, CancellationToken.None); } result.Should().NotBeNull(); @@ -484,11 +484,11 @@ public async void SelectServer_should_not_deprioritize_if_there_no_servers_to_de IServer result; if (async) { - result = await subject.SelectServerAsync(selector, CancellationToken.None); + result = await subject.SelectServerAsync(selector, null, CancellationToken.None); } else { - result = subject.SelectServer(selector, CancellationToken.None); + result = subject.SelectServer(selector, null, CancellationToken.None); } result.Should().NotBeNull(); @@ -529,11 +529,11 @@ public async void SelectServer_should_return_deprioritized_servers_if_no_other_s IServer result; if (async) { - result = await subject.SelectServerAsync(selector, CancellationToken.None, deprioritizedServers); + result = await subject.SelectServerAsync(selector, deprioritizedServers, CancellationToken.None); } else { - result = subject.SelectServer(selector, CancellationToken.None, deprioritizedServers); + result = subject.SelectServer(selector, deprioritizedServers, CancellationToken.None); } result.Should().NotBeNull(); diff --git a/tests/MongoDB.Driver.Tests/Encryption/ClientEncryptionTests.cs b/tests/MongoDB.Driver.Tests/Encryption/ClientEncryptionTests.cs index 5eee6c743ff..a5456c9952c 100644 --- a/tests/MongoDB.Driver.Tests/Encryption/ClientEncryptionTests.cs +++ b/tests/MongoDB.Driver.Tests/Encryption/ClientEncryptionTests.cs @@ -140,10 +140,10 @@ public async Task CreateEncryptedCollection_should_handle_generated_key_when_sec mockServer.Setup(s => s.GetChannelAsync(It.IsAny())).ReturnsAsync(channel); mockCluster - .Setup(m => m.SelectServer(It.IsAny(), It.IsAny(), null)) + .Setup(m => m.SelectServer(It.IsAny(), null, It.IsAny())) .Returns(mockServer.Object); mockCluster - .Setup(m => m.SelectServerAsync(It.IsAny(), It.IsAny(), null)) + .Setup(m => m.SelectServerAsync(It.IsAny(), null, It.IsAny())) .ReturnsAsync(mockServer.Object); var database = Mock.Of(d => @@ -229,10 +229,10 @@ public async Task CreateEncryptedCollection_should_handle_various_encryptedField mockServer.Setup(s => s.GetChannelAsync(It.IsAny())).ReturnsAsync(channel); mockCluster - .Setup(m => m.SelectServer(It.IsAny(), It.IsAny(), null)) + .Setup(m => m.SelectServer(It.IsAny(), null, It.IsAny())) .Returns(mockServer.Object); mockCluster - .Setup(m => m.SelectServerAsync(It.IsAny(), It.IsAny(), null)) + .Setup(m => m.SelectServerAsync(It.IsAny(), null, It.IsAny())) .ReturnsAsync(mockServer.Object); var database = Mock.Of(d => From 2f34978e0dd2a009b5968eee938665956425fb37 Mon Sep 17 00:00:00 2001 From: adelinowona Date: Mon, 29 Apr 2024 18:47:08 -0400 Subject: [PATCH 13/24] Revert "remove unnecessary white space" This reverts commit 3e6d403aaae1bf136267eda115fc8ee99c29e6a6. --- .../Core/Bindings/ChannelReadBinding.cs | 4 ++-- .../Core/Bindings/ChannelReadWriteBinding.cs | 12 ++++++------ .../Core/Bindings/ChannelSourceReadWriteBinding.cs | 12 ++++++------ .../Core/Bindings/ReadBindingHandle.cs | 4 ++-- .../Core/Bindings/ReadPreferenceBinding.cs | 4 ++-- .../Core/Bindings/ReadWriteBindingHandle.cs | 12 ++++++------ .../Core/Bindings/SingleServerReadBinding.cs | 4 ++-- .../Core/Bindings/SingleServerReadWriteBinding.cs | 12 ++++++------ .../Core/Bindings/WritableServerBinding.cs | 12 ++++++------ 9 files changed, 38 insertions(+), 38 deletions(-) diff --git a/src/MongoDB.Driver.Core/Core/Bindings/ChannelReadBinding.cs b/src/MongoDB.Driver.Core/Core/Bindings/ChannelReadBinding.cs index b16961a5c7a..ff5699f60c0 100644 --- a/src/MongoDB.Driver.Core/Core/Bindings/ChannelReadBinding.cs +++ b/src/MongoDB.Driver.Core/Core/Bindings/ChannelReadBinding.cs @@ -75,14 +75,14 @@ public void Dispose() } } - /// + /// public IChannelSourceHandle GetReadChannelSource(CancellationToken cancellationToken, IReadOnlyCollection deprioritizedServers = null) { ThrowIfDisposed(); return GetReadChannelSourceHelper(); } - /// + /// public Task GetReadChannelSourceAsync(CancellationToken cancellationToken, IReadOnlyCollection deprioritizedServers = null) { ThrowIfDisposed(); diff --git a/src/MongoDB.Driver.Core/Core/Bindings/ChannelReadWriteBinding.cs b/src/MongoDB.Driver.Core/Core/Bindings/ChannelReadWriteBinding.cs index 0bf3e39d2a7..29624f77cf4 100644 --- a/src/MongoDB.Driver.Core/Core/Bindings/ChannelReadWriteBinding.cs +++ b/src/MongoDB.Driver.Core/Core/Bindings/ChannelReadWriteBinding.cs @@ -72,41 +72,41 @@ public void Dispose() } } - /// + /// public IChannelSourceHandle GetReadChannelSource(CancellationToken cancellationToken, IReadOnlyCollection deprioritizedServers = null) { ThrowIfDisposed(); return GetChannelSourceHelper(); } - /// + /// public Task GetReadChannelSourceAsync(CancellationToken cancellationToken, IReadOnlyCollection deprioritizedServers = null) { ThrowIfDisposed(); return Task.FromResult(GetChannelSourceHelper()); } - /// + /// public IChannelSourceHandle GetWriteChannelSource(CancellationToken cancellationToken, IReadOnlyCollection deprioritizedServers = null) { ThrowIfDisposed(); return GetChannelSourceHelper(); } - /// + /// public IChannelSourceHandle GetWriteChannelSource(IMayUseSecondaryCriteria mayUseSecondary, CancellationToken cancellationToken, IReadOnlyCollection deprioritizedServers = null) { return GetWriteChannelSource(cancellationToken, deprioritizedServers); // ignore mayUseSecondary } - /// + /// public Task GetWriteChannelSourceAsync(CancellationToken cancellationToken, IReadOnlyCollection deprioritizedServers = null) { ThrowIfDisposed(); return Task.FromResult(GetChannelSourceHelper()); } - /// + /// public Task GetWriteChannelSourceAsync(IMayUseSecondaryCriteria mayUseSecondary, CancellationToken cancellationToken, IReadOnlyCollection deprioritizedServers = null) { return GetWriteChannelSourceAsync(cancellationToken, deprioritizedServers); // ignore mayUseSecondary diff --git a/src/MongoDB.Driver.Core/Core/Bindings/ChannelSourceReadWriteBinding.cs b/src/MongoDB.Driver.Core/Core/Bindings/ChannelSourceReadWriteBinding.cs index d01f75cfc71..6aa976db82a 100644 --- a/src/MongoDB.Driver.Core/Core/Bindings/ChannelSourceReadWriteBinding.cs +++ b/src/MongoDB.Driver.Core/Core/Bindings/ChannelSourceReadWriteBinding.cs @@ -61,41 +61,41 @@ public ICoreSessionHandle Session } // methods - /// + /// public IChannelSourceHandle GetReadChannelSource(CancellationToken cancellationToken, IReadOnlyCollection deprioritizedServers = null) { ThrowIfDisposed(); return GetChannelSourceHelper(); } - /// + /// public Task GetReadChannelSourceAsync(CancellationToken cancellationToken, IReadOnlyCollection deprioritizedServers = null) { ThrowIfDisposed(); return Task.FromResult(GetChannelSourceHelper()); } - /// + /// public IChannelSourceHandle GetWriteChannelSource(CancellationToken cancellationToken, IReadOnlyCollection deprioritizedServers = null) { ThrowIfDisposed(); return GetChannelSourceHelper(); } - /// + /// public IChannelSourceHandle GetWriteChannelSource(IMayUseSecondaryCriteria mayUseSecondary, CancellationToken cancellationToken, IReadOnlyCollection deprioritizedServers = null) { return GetWriteChannelSource(cancellationToken, deprioritizedServers); // ignore mayUseSecondary } - /// + /// public Task GetWriteChannelSourceAsync(CancellationToken cancellationToken, IReadOnlyCollection deprioritizedServers = null) { ThrowIfDisposed(); return Task.FromResult(GetChannelSourceHelper()); } - /// + /// public Task GetWriteChannelSourceAsync(IMayUseSecondaryCriteria mayUseSecondary, CancellationToken cancellationToken, IReadOnlyCollection deprioritizedServers = null) { return GetWriteChannelSourceAsync(cancellationToken, deprioritizedServers); // ignore mayUseSecondary diff --git a/src/MongoDB.Driver.Core/Core/Bindings/ReadBindingHandle.cs b/src/MongoDB.Driver.Core/Core/Bindings/ReadBindingHandle.cs index 53ee61378a8..8d9e448f5db 100644 --- a/src/MongoDB.Driver.Core/Core/Bindings/ReadBindingHandle.cs +++ b/src/MongoDB.Driver.Core/Core/Bindings/ReadBindingHandle.cs @@ -59,14 +59,14 @@ public ICoreSessionHandle Session get { return _reference.Instance.Session; } } - /// + /// public IChannelSourceHandle GetReadChannelSource(CancellationToken cancellationToken, IReadOnlyCollection deprioritizedServers = null) { ThrowIfDisposed(); return _reference.Instance.GetReadChannelSource(cancellationToken, deprioritizedServers); } - /// + /// public Task GetReadChannelSourceAsync(CancellationToken cancellationToken, IReadOnlyCollection deprioritizedServers = null) { ThrowIfDisposed(); diff --git a/src/MongoDB.Driver.Core/Core/Bindings/ReadPreferenceBinding.cs b/src/MongoDB.Driver.Core/Core/Bindings/ReadPreferenceBinding.cs index e1a72003a67..26c0868463a 100644 --- a/src/MongoDB.Driver.Core/Core/Bindings/ReadPreferenceBinding.cs +++ b/src/MongoDB.Driver.Core/Core/Bindings/ReadPreferenceBinding.cs @@ -65,7 +65,7 @@ public ICoreSessionHandle Session } // methods - /// + /// public IChannelSourceHandle GetReadChannelSource(CancellationToken cancellationToken, IReadOnlyCollection deprioritizedServers = null) { ThrowIfDisposed(); @@ -73,7 +73,7 @@ public IChannelSourceHandle GetReadChannelSource(CancellationToken cancellationT return GetChannelSourceHelper(server); } - /// + /// public async Task GetReadChannelSourceAsync(CancellationToken cancellationToken, IReadOnlyCollection deprioritizedServers = null) { ThrowIfDisposed(); diff --git a/src/MongoDB.Driver.Core/Core/Bindings/ReadWriteBindingHandle.cs b/src/MongoDB.Driver.Core/Core/Bindings/ReadWriteBindingHandle.cs index 73c97d697be..c43c4ab05c0 100644 --- a/src/MongoDB.Driver.Core/Core/Bindings/ReadWriteBindingHandle.cs +++ b/src/MongoDB.Driver.Core/Core/Bindings/ReadWriteBindingHandle.cs @@ -59,42 +59,42 @@ public ICoreSessionHandle Session get { return _reference.Instance.Session; } } - /// + /// public IChannelSourceHandle GetReadChannelSource(CancellationToken cancellationToken, IReadOnlyCollection deprioritizedServers = null) { ThrowIfDisposed(); return _reference.Instance.GetReadChannelSource(cancellationToken, deprioritizedServers); } - /// + /// public Task GetReadChannelSourceAsync(CancellationToken cancellationToken, IReadOnlyCollection deprioritizedServers = null) { ThrowIfDisposed(); return _reference.Instance.GetReadChannelSourceAsync(cancellationToken, deprioritizedServers); } - /// + /// public IChannelSourceHandle GetWriteChannelSource(CancellationToken cancellationToken, IReadOnlyCollection deprioritizedServers = null) { ThrowIfDisposed(); return _reference.Instance.GetWriteChannelSource(cancellationToken, deprioritizedServers); } - /// + /// public IChannelSourceHandle GetWriteChannelSource(IMayUseSecondaryCriteria mayUseSecondary, CancellationToken cancellationToken, IReadOnlyCollection deprioritizedServers = null) { ThrowIfDisposed(); return _reference.Instance.GetWriteChannelSource(mayUseSecondary, cancellationToken, deprioritizedServers); } - /// + /// public Task GetWriteChannelSourceAsync(CancellationToken cancellationToken, IReadOnlyCollection deprioritizedServers = null) { ThrowIfDisposed(); return _reference.Instance.GetWriteChannelSourceAsync(cancellationToken, deprioritizedServers); } - /// + /// public Task GetWriteChannelSourceAsync(IMayUseSecondaryCriteria mayUseSecondary, CancellationToken cancellationToken, IReadOnlyCollection deprioritizedServers = null) { ThrowIfDisposed(); diff --git a/src/MongoDB.Driver.Core/Core/Bindings/SingleServerReadBinding.cs b/src/MongoDB.Driver.Core/Core/Bindings/SingleServerReadBinding.cs index e12524c2355..28cb59c095c 100644 --- a/src/MongoDB.Driver.Core/Core/Bindings/SingleServerReadBinding.cs +++ b/src/MongoDB.Driver.Core/Core/Bindings/SingleServerReadBinding.cs @@ -64,14 +64,14 @@ public ICoreSessionHandle Session } // methods - /// + /// public IChannelSourceHandle GetReadChannelSource(CancellationToken cancellationToken, IReadOnlyCollection deprioritizedServers = null) { ThrowIfDisposed(); return GetChannelSourceHelper(); } - /// + /// public Task GetReadChannelSourceAsync(CancellationToken cancellationToken, IReadOnlyCollection deprioritizedServers = null) { ThrowIfDisposed(); diff --git a/src/MongoDB.Driver.Core/Core/Bindings/SingleServerReadWriteBinding.cs b/src/MongoDB.Driver.Core/Core/Bindings/SingleServerReadWriteBinding.cs index a8d5359f11b..ec849cde1f2 100644 --- a/src/MongoDB.Driver.Core/Core/Bindings/SingleServerReadWriteBinding.cs +++ b/src/MongoDB.Driver.Core/Core/Bindings/SingleServerReadWriteBinding.cs @@ -68,41 +68,41 @@ public void Dispose() } } - /// + /// public IChannelSourceHandle GetReadChannelSource(CancellationToken cancellationToken, IReadOnlyCollection deprioritizedServers = null) { ThrowIfDisposed(); return GetChannelSourceHelper(); } - /// + /// public Task GetReadChannelSourceAsync(CancellationToken cancellationToken, IReadOnlyCollection deprioritizedServers = null) { ThrowIfDisposed(); return Task.FromResult(GetChannelSourceHelper()); } - /// + /// public IChannelSourceHandle GetWriteChannelSource(CancellationToken cancellationToken, IReadOnlyCollection deprioritizedServers = null) { ThrowIfDisposed(); return GetChannelSourceHelper(); } - /// + /// public IChannelSourceHandle GetWriteChannelSource(IMayUseSecondaryCriteria mayUseSecondary, CancellationToken cancellationToken, IReadOnlyCollection deprioritizedServers = null) { return GetWriteChannelSource(cancellationToken, deprioritizedServers); // ignore mayUseSecondary } - /// + /// public Task GetWriteChannelSourceAsync(CancellationToken cancellationToken, IReadOnlyCollection deprioritizedServers = null) { ThrowIfDisposed(); return Task.FromResult(GetChannelSourceHelper()); } - /// + /// public Task GetWriteChannelSourceAsync(IMayUseSecondaryCriteria mayUseSecondary, CancellationToken cancellationToken, IReadOnlyCollection deprioritizedServers = null) { return GetWriteChannelSourceAsync(cancellationToken, deprioritizedServers); // ignore mayUseSecondary diff --git a/src/MongoDB.Driver.Core/Core/Bindings/WritableServerBinding.cs b/src/MongoDB.Driver.Core/Core/Bindings/WritableServerBinding.cs index dbcc47aa3ba..52d28a61914 100644 --- a/src/MongoDB.Driver.Core/Core/Bindings/WritableServerBinding.cs +++ b/src/MongoDB.Driver.Core/Core/Bindings/WritableServerBinding.cs @@ -60,7 +60,7 @@ public ICoreSessionHandle Session } // methods - /// + /// public IChannelSourceHandle GetReadChannelSource(CancellationToken cancellationToken, IReadOnlyCollection deprioritizedServers = null) { ThrowIfDisposed(); @@ -68,7 +68,7 @@ public IChannelSourceHandle GetReadChannelSource(CancellationToken cancellationT return CreateServerChannelSource(server); } - /// + /// public async Task GetReadChannelSourceAsync(CancellationToken cancellationToken, IReadOnlyCollection deprioritizedServers = null) { ThrowIfDisposed(); @@ -76,7 +76,7 @@ public async Task GetReadChannelSourceAsync(CancellationTo return CreateServerChannelSource(server); } - /// + /// public IChannelSourceHandle GetWriteChannelSource(CancellationToken cancellationToken, IReadOnlyCollection deprioritizedServers = null) { ThrowIfDisposed(); @@ -84,7 +84,7 @@ public IChannelSourceHandle GetWriteChannelSource(CancellationToken cancellation return CreateServerChannelSource(server); } - /// + /// public IChannelSourceHandle GetWriteChannelSource(IMayUseSecondaryCriteria mayUseSecondary, CancellationToken cancellationToken, IReadOnlyCollection deprioritizedServers = null) { if (IsSessionPinnedToServer()) @@ -97,7 +97,7 @@ public IChannelSourceHandle GetWriteChannelSource(IMayUseSecondaryCriteria mayUs return CreateServerChannelSource(server); } - /// + /// public async Task GetWriteChannelSourceAsync(CancellationToken cancellationToken, IReadOnlyCollection deprioritizedServers = null) { ThrowIfDisposed(); @@ -105,7 +105,7 @@ public async Task GetWriteChannelSourceAsync(CancellationT return CreateServerChannelSource(server); } - /// + /// public async Task GetWriteChannelSourceAsync(IMayUseSecondaryCriteria mayUseSecondary, CancellationToken cancellationToken, IReadOnlyCollection deprioritizedServers = null) { if (IsSessionPinnedToServer()) From 83eda80deb56bbac34020da18fc166448cb54885 Mon Sep 17 00:00:00 2001 From: adelinowona Date: Mon, 29 Apr 2024 18:47:08 -0400 Subject: [PATCH 14/24] Revert "Incorporate review feedback" This reverts commit 49995fd69a7620b9b0af96269a00310e654995f1. --- .../Core/Bindings/ChannelReadBinding.cs | 20 ++++-- .../Core/Bindings/ChannelReadWriteBinding.cs | 56 ++++++++++++--- .../Bindings/ChannelSourceReadWriteBinding.cs | 56 ++++++++++++--- .../Core/Bindings/IBinding.cs | 68 +++++++++++++++---- .../Core/Bindings/ReadBindingHandle.cs | 23 +++++-- .../Core/Bindings/ReadPreferenceBinding.cs | 16 ++++- .../Core/Bindings/ReadWriteBindingHandle.cs | 67 ++++++++++++++---- .../Core/Bindings/SingleServerReadBinding.cs | 20 ++++-- .../Bindings/SingleServerReadWriteBinding.cs | 56 ++++++++++++--- .../Core/Bindings/WritableServerBinding.cs | 48 +++++++++++-- .../RetryableReadOperationExecutor.cs | 4 +- .../RetryableWriteOperationExecutor.cs | 4 +- .../Core/Bindings/ReadBindingHandleTests.cs | 4 +- .../Bindings/ReadWriteBindingHandleTests.cs | 8 +-- .../Core/Clusters/ClusterTests.cs | 57 +++------------- .../Operations/ReadCommandOperationTests.cs | 4 +- .../RetryableWriteOperationExecutorTests.cs | 2 +- .../Operations/WriteCommandOperationTests.cs | 4 +- 18 files changed, 381 insertions(+), 136 deletions(-) diff --git a/src/MongoDB.Driver.Core/Core/Bindings/ChannelReadBinding.cs b/src/MongoDB.Driver.Core/Core/Bindings/ChannelReadBinding.cs index ff5699f60c0..c91671dfa75 100644 --- a/src/MongoDB.Driver.Core/Core/Bindings/ChannelReadBinding.cs +++ b/src/MongoDB.Driver.Core/Core/Bindings/ChannelReadBinding.cs @@ -75,20 +75,32 @@ public void Dispose() } } - /// - public IChannelSourceHandle GetReadChannelSource(CancellationToken cancellationToken, IReadOnlyCollection deprioritizedServers = null) + /// + public IChannelSourceHandle GetReadChannelSource(CancellationToken cancellationToken) { ThrowIfDisposed(); return GetReadChannelSourceHelper(); } - /// - public Task GetReadChannelSourceAsync(CancellationToken cancellationToken, IReadOnlyCollection deprioritizedServers = null) + /// + public Task GetReadChannelSourceAsync(CancellationToken cancellationToken) { ThrowIfDisposed(); return Task.FromResult(GetReadChannelSourceHelper()); } + /// + public IChannelSourceHandle GetReadChannelSource(IReadOnlyCollection deprioritizedServers, CancellationToken cancellationToken) + { + return GetReadChannelSource(cancellationToken); + } + + /// + public Task GetReadChannelSourceAsync(IReadOnlyCollection deprioritizedServers, CancellationToken cancellationToken) + { + return GetReadChannelSourceAsync(cancellationToken); + } + private IChannelSourceHandle GetReadChannelSourceHelper() { return new ChannelSourceHandle(new ChannelChannelSource(_server, _channel.Fork(), _session.Fork())); diff --git a/src/MongoDB.Driver.Core/Core/Bindings/ChannelReadWriteBinding.cs b/src/MongoDB.Driver.Core/Core/Bindings/ChannelReadWriteBinding.cs index 29624f77cf4..2e8bf6695f3 100644 --- a/src/MongoDB.Driver.Core/Core/Bindings/ChannelReadWriteBinding.cs +++ b/src/MongoDB.Driver.Core/Core/Bindings/ChannelReadWriteBinding.cs @@ -72,44 +72,80 @@ public void Dispose() } } - /// - public IChannelSourceHandle GetReadChannelSource(CancellationToken cancellationToken, IReadOnlyCollection deprioritizedServers = null) + /// + public IChannelSourceHandle GetReadChannelSource(CancellationToken cancellationToken) { ThrowIfDisposed(); return GetChannelSourceHelper(); } - /// - public Task GetReadChannelSourceAsync(CancellationToken cancellationToken, IReadOnlyCollection deprioritizedServers = null) + /// + public Task GetReadChannelSourceAsync(CancellationToken cancellationToken) { ThrowIfDisposed(); return Task.FromResult(GetChannelSourceHelper()); } /// - public IChannelSourceHandle GetWriteChannelSource(CancellationToken cancellationToken, IReadOnlyCollection deprioritizedServers = null) + public IChannelSourceHandle GetReadChannelSource(IReadOnlyCollection deprioritizedServers, CancellationToken cancellationToken) + { + return GetReadChannelSource(cancellationToken); + } + + /// + public Task GetReadChannelSourceAsync(IReadOnlyCollection deprioritizedServers, CancellationToken cancellationToken) + { + return GetReadChannelSourceAsync(cancellationToken); + } + + /// + public IChannelSourceHandle GetWriteChannelSource(CancellationToken cancellationToken) { ThrowIfDisposed(); return GetChannelSourceHelper(); } /// - public IChannelSourceHandle GetWriteChannelSource(IMayUseSecondaryCriteria mayUseSecondary, CancellationToken cancellationToken, IReadOnlyCollection deprioritizedServers = null) + public IChannelSourceHandle GetWriteChannelSource(IReadOnlyCollection deprioritizedServers, CancellationToken cancellationToken) + { + return GetWriteChannelSource(cancellationToken); + } + + /// + public IChannelSourceHandle GetWriteChannelSource(IMayUseSecondaryCriteria mayUseSecondary, CancellationToken cancellationToken) { - return GetWriteChannelSource(cancellationToken, deprioritizedServers); // ignore mayUseSecondary + return GetWriteChannelSource(cancellationToken); // ignore mayUseSecondary } /// - public Task GetWriteChannelSourceAsync(CancellationToken cancellationToken, IReadOnlyCollection deprioritizedServers = null) + public IChannelSourceHandle GetWriteChannelSource(IReadOnlyCollection deprioritizedServers, IMayUseSecondaryCriteria mayUseSecondary, CancellationToken cancellationToken) + { + return GetWriteChannelSource(mayUseSecondary, cancellationToken); + } + + /// + public Task GetWriteChannelSourceAsync(CancellationToken cancellationToken) { ThrowIfDisposed(); return Task.FromResult(GetChannelSourceHelper()); } /// - public Task GetWriteChannelSourceAsync(IMayUseSecondaryCriteria mayUseSecondary, CancellationToken cancellationToken, IReadOnlyCollection deprioritizedServers = null) + public Task GetWriteChannelSourceAsync(IReadOnlyCollection deprioritizedServers, CancellationToken cancellationToken) + { + return GetWriteChannelSourceAsync(cancellationToken); + } + + /// + public Task GetWriteChannelSourceAsync(IMayUseSecondaryCriteria mayUseSecondary, CancellationToken cancellationToken) + { + return GetWriteChannelSourceAsync(cancellationToken); // ignore mayUseSecondary + } + + /// + public Task GetWriteChannelSourceAsync(IReadOnlyCollection deprioritizedServers, IMayUseSecondaryCriteria mayUseSecondary, CancellationToken cancellationToken) { - return GetWriteChannelSourceAsync(cancellationToken, deprioritizedServers); // ignore mayUseSecondary + return GetWriteChannelSourceAsync(mayUseSecondary, cancellationToken); } // private methods diff --git a/src/MongoDB.Driver.Core/Core/Bindings/ChannelSourceReadWriteBinding.cs b/src/MongoDB.Driver.Core/Core/Bindings/ChannelSourceReadWriteBinding.cs index 6aa976db82a..e434a36a57b 100644 --- a/src/MongoDB.Driver.Core/Core/Bindings/ChannelSourceReadWriteBinding.cs +++ b/src/MongoDB.Driver.Core/Core/Bindings/ChannelSourceReadWriteBinding.cs @@ -61,44 +61,80 @@ public ICoreSessionHandle Session } // methods - /// - public IChannelSourceHandle GetReadChannelSource(CancellationToken cancellationToken, IReadOnlyCollection deprioritizedServers = null) + /// + public IChannelSourceHandle GetReadChannelSource(CancellationToken cancellationToken) { ThrowIfDisposed(); return GetChannelSourceHelper(); } - /// - public Task GetReadChannelSourceAsync(CancellationToken cancellationToken, IReadOnlyCollection deprioritizedServers = null) + /// + public Task GetReadChannelSourceAsync(CancellationToken cancellationToken) { ThrowIfDisposed(); return Task.FromResult(GetChannelSourceHelper()); } /// - public IChannelSourceHandle GetWriteChannelSource(CancellationToken cancellationToken, IReadOnlyCollection deprioritizedServers = null) + public IChannelSourceHandle GetReadChannelSource(IReadOnlyCollection deprioritizedServers, CancellationToken cancellationToken) + { + return GetReadChannelSource(cancellationToken); + } + + /// + public Task GetReadChannelSourceAsync(IReadOnlyCollection deprioritizedServers, CancellationToken cancellationToken) + { + return GetReadChannelSourceAsync(cancellationToken); + } + + /// + public IChannelSourceHandle GetWriteChannelSource(CancellationToken cancellationToken) { ThrowIfDisposed(); return GetChannelSourceHelper(); } /// - public IChannelSourceHandle GetWriteChannelSource(IMayUseSecondaryCriteria mayUseSecondary, CancellationToken cancellationToken, IReadOnlyCollection deprioritizedServers = null) + public IChannelSourceHandle GetWriteChannelSource(IReadOnlyCollection deprioritizedServers, CancellationToken cancellationToken) + { + return GetWriteChannelSource(cancellationToken); + } + + /// + public IChannelSourceHandle GetWriteChannelSource(IMayUseSecondaryCriteria mayUseSecondary, CancellationToken cancellationToken) { - return GetWriteChannelSource(cancellationToken, deprioritizedServers); // ignore mayUseSecondary + return GetWriteChannelSource(cancellationToken); // ignore mayUseSecondary } /// - public Task GetWriteChannelSourceAsync(CancellationToken cancellationToken, IReadOnlyCollection deprioritizedServers = null) + public IChannelSourceHandle GetWriteChannelSource(IReadOnlyCollection deprioritizedServers, IMayUseSecondaryCriteria mayUseSecondary, CancellationToken cancellationToken) + { + return GetWriteChannelSource(mayUseSecondary, cancellationToken); + } + + /// + public Task GetWriteChannelSourceAsync(CancellationToken cancellationToken) { ThrowIfDisposed(); return Task.FromResult(GetChannelSourceHelper()); } /// - public Task GetWriteChannelSourceAsync(IMayUseSecondaryCriteria mayUseSecondary, CancellationToken cancellationToken, IReadOnlyCollection deprioritizedServers = null) + public Task GetWriteChannelSourceAsync(IReadOnlyCollection deprioritizedServers, CancellationToken cancellationToken) + { + return GetWriteChannelSourceAsync(cancellationToken); + } + + /// + public Task GetWriteChannelSourceAsync(IMayUseSecondaryCriteria mayUseSecondary, CancellationToken cancellationToken) + { + return GetWriteChannelSourceAsync(cancellationToken); // ignore mayUseSecondary + } + + /// + public Task GetWriteChannelSourceAsync(IReadOnlyCollection deprioritizedServers, IMayUseSecondaryCriteria mayUseSecondary, CancellationToken cancellationToken) { - return GetWriteChannelSourceAsync(cancellationToken, deprioritizedServers); // ignore mayUseSecondary + return GetWriteChannelSourceAsync(mayUseSecondary, cancellationToken); } /// diff --git a/src/MongoDB.Driver.Core/Core/Bindings/IBinding.cs b/src/MongoDB.Driver.Core/Core/Bindings/IBinding.cs index 1f6106af757..40c33ee441c 100644 --- a/src/MongoDB.Driver.Core/Core/Bindings/IBinding.cs +++ b/src/MongoDB.Driver.Core/Core/Bindings/IBinding.cs @@ -50,20 +50,34 @@ public interface IReadBinding : IBinding ReadPreference ReadPreference { get; } /// - /// Gets a channel source for read operations while deprioritizing servers in the provided collection. + /// Gets a channel source for read operations. /// /// The cancellation token. - /// The deprioritized servers. /// A channel source. - IChannelSourceHandle GetReadChannelSource(CancellationToken cancellationToken, IReadOnlyCollection deprioritizedServers = null); + IChannelSourceHandle GetReadChannelSource(CancellationToken cancellationToken); + + /// + /// Gets a channel source for read operations. + /// + /// The cancellation token. + /// A channel source. + Task GetReadChannelSourceAsync(CancellationToken cancellationToken); /// /// Gets a channel source for read operations while deprioritizing servers in the provided collection. /// + /// The deprioritized servers. /// The cancellation token. + /// A channel source. + IChannelSourceHandle GetReadChannelSource(IReadOnlyCollection deprioritizedServers, CancellationToken cancellationToken); + + /// + /// Gets a channel source for read operations while deprioritizing servers in the provided collection. + /// /// The deprioritized servers. + /// The cancellation token. /// A channel source. - Task GetReadChannelSourceAsync(CancellationToken cancellationToken, IReadOnlyCollection deprioritizedServers = null); + Task GetReadChannelSourceAsync(IReadOnlyCollection deprioritizedServers, CancellationToken cancellationToken); } /// @@ -72,38 +86,68 @@ public interface IReadBinding : IBinding public interface IWriteBinding : IBinding { /// - /// Gets a channel source for write operations while deprioritizing servers in the provided collection. + /// Gets a channel source for write operations. /// /// The cancellation token. + /// A channel source. + IChannelSourceHandle GetWriteChannelSource(CancellationToken cancellationToken); + + /// + /// Gets a channel source for write operations while deprioritizing servers in the provided collection. + /// /// The deprioritized servers. + /// The cancellation token. /// A channel source. - IChannelSourceHandle GetWriteChannelSource(CancellationToken cancellationToken, IReadOnlyCollection deprioritizedServers = null); + IChannelSourceHandle GetWriteChannelSource(IReadOnlyCollection deprioritizedServers, CancellationToken cancellationToken); /// - /// Gets a channel source for write operations that may use a secondary and deprioritizes servers in the provided collection. + /// Gets a channel source for write operations that may use a secondary. /// /// The may use secondary criteria. /// The cancellation token. + /// A channel source. + IChannelSourceHandle GetWriteChannelSource(IMayUseSecondaryCriteria mayUseSecondary, CancellationToken cancellationToken); + + /// + /// Gets a channel source for write operations that may use a secondary and deprioritizes servers in the provided collection. + /// /// The deprioritized servers. + /// The may use secondary criteria. + /// The cancellation token. /// A channel source. - IChannelSourceHandle GetWriteChannelSource(IMayUseSecondaryCriteria mayUseSecondary, CancellationToken cancellationToken, IReadOnlyCollection deprioritizedServers = null); + IChannelSourceHandle GetWriteChannelSource(IReadOnlyCollection deprioritizedServers, IMayUseSecondaryCriteria mayUseSecondary, CancellationToken cancellationToken); /// - /// Gets a channel source for write operations while deprioritizing servers in the provided collection. + /// Gets a channel source for write operations. /// /// The cancellation token. + /// A channel source. + Task GetWriteChannelSourceAsync(CancellationToken cancellationToken); + + /// + /// Gets a channel source for write operations while deprioritizing servers in the provided collection. + /// /// The deprioritized servers. + /// The cancellation token. /// A channel source. - Task GetWriteChannelSourceAsync(CancellationToken cancellationToken, IReadOnlyCollection deprioritizedServers = null); + Task GetWriteChannelSourceAsync(IReadOnlyCollection deprioritizedServers, CancellationToken cancellationToken); /// - /// Gets a channel source for write operations that may use a secondary and deprioritizes servers in the provided collection. + /// Gets a channel source for write operations that may use a secondary. /// /// The may use secondary criteria. /// The cancellation token. + /// A channel source. + Task GetWriteChannelSourceAsync(IMayUseSecondaryCriteria mayUseSecondary, CancellationToken cancellationToken); + + /// + /// Gets a channel source for write operations that may use a secondary and deprioritizes servers in the provided collection. + /// /// The deprioritized servers. + /// The may use secondary criteria. + /// The cancellation token. /// A channel source. - Task GetWriteChannelSourceAsync(IMayUseSecondaryCriteria mayUseSecondary, CancellationToken cancellationToken, IReadOnlyCollection deprioritizedServers = null); + Task GetWriteChannelSourceAsync(IReadOnlyCollection deprioritizedServers, IMayUseSecondaryCriteria mayUseSecondary, CancellationToken cancellationToken); } /// diff --git a/src/MongoDB.Driver.Core/Core/Bindings/ReadBindingHandle.cs b/src/MongoDB.Driver.Core/Core/Bindings/ReadBindingHandle.cs index 8d9e448f5db..6c8283d2bfd 100644 --- a/src/MongoDB.Driver.Core/Core/Bindings/ReadBindingHandle.cs +++ b/src/MongoDB.Driver.Core/Core/Bindings/ReadBindingHandle.cs @@ -59,18 +59,33 @@ public ICoreSessionHandle Session get { return _reference.Instance.Session; } } + // methods + /// + public IChannelSourceHandle GetReadChannelSource(CancellationToken cancellationToken) + { + ThrowIfDisposed(); + return _reference.Instance.GetReadChannelSource(cancellationToken); + } + + /// + public Task GetReadChannelSourceAsync(CancellationToken cancellationToken) + { + ThrowIfDisposed(); + return _reference.Instance.GetReadChannelSourceAsync(cancellationToken); + } + /// - public IChannelSourceHandle GetReadChannelSource(CancellationToken cancellationToken, IReadOnlyCollection deprioritizedServers = null) + public IChannelSourceHandle GetReadChannelSource(IReadOnlyCollection deprioritizedServers, CancellationToken cancellationToken) { ThrowIfDisposed(); - return _reference.Instance.GetReadChannelSource(cancellationToken, deprioritizedServers); + return _reference.Instance.GetReadChannelSource(deprioritizedServers, cancellationToken); } /// - public Task GetReadChannelSourceAsync(CancellationToken cancellationToken, IReadOnlyCollection deprioritizedServers = null) + public Task GetReadChannelSourceAsync(IReadOnlyCollection deprioritizedServers, CancellationToken cancellationToken) { ThrowIfDisposed(); - return _reference.Instance.GetReadChannelSourceAsync(cancellationToken, deprioritizedServers); + return _reference.Instance.GetReadChannelSourceAsync(deprioritizedServers, cancellationToken); } /// diff --git a/src/MongoDB.Driver.Core/Core/Bindings/ReadPreferenceBinding.cs b/src/MongoDB.Driver.Core/Core/Bindings/ReadPreferenceBinding.cs index 26c0868463a..4bd662f53a7 100644 --- a/src/MongoDB.Driver.Core/Core/Bindings/ReadPreferenceBinding.cs +++ b/src/MongoDB.Driver.Core/Core/Bindings/ReadPreferenceBinding.cs @@ -65,8 +65,20 @@ public ICoreSessionHandle Session } // methods + /// + public IChannelSourceHandle GetReadChannelSource(CancellationToken cancellationToken) + { + return GetReadChannelSource(null, cancellationToken); + } + + /// + public async Task GetReadChannelSourceAsync(CancellationToken cancellationToken) + { + return await GetReadChannelSourceAsync(null, cancellationToken).ConfigureAwait(false); + } + /// - public IChannelSourceHandle GetReadChannelSource(CancellationToken cancellationToken, IReadOnlyCollection deprioritizedServers = null) + public IChannelSourceHandle GetReadChannelSource(IReadOnlyCollection deprioritizedServers, CancellationToken cancellationToken) { ThrowIfDisposed(); var server = _cluster.SelectServerAndPinIfNeeded(_session, _serverSelector, deprioritizedServers, cancellationToken); @@ -74,7 +86,7 @@ public IChannelSourceHandle GetReadChannelSource(CancellationToken cancellationT } /// - public async Task GetReadChannelSourceAsync(CancellationToken cancellationToken, IReadOnlyCollection deprioritizedServers = null) + public async Task GetReadChannelSourceAsync(IReadOnlyCollection deprioritizedServers, CancellationToken cancellationToken) { ThrowIfDisposed(); var server = await _cluster.SelectServerAndPinIfNeededAsync(_session, _serverSelector, deprioritizedServers, cancellationToken).ConfigureAwait(false); diff --git a/src/MongoDB.Driver.Core/Core/Bindings/ReadWriteBindingHandle.cs b/src/MongoDB.Driver.Core/Core/Bindings/ReadWriteBindingHandle.cs index c43c4ab05c0..205e47dfdf4 100644 --- a/src/MongoDB.Driver.Core/Core/Bindings/ReadWriteBindingHandle.cs +++ b/src/MongoDB.Driver.Core/Core/Bindings/ReadWriteBindingHandle.cs @@ -59,46 +59,89 @@ public ICoreSessionHandle Session get { return _reference.Instance.Session; } } + // methods + /// + public IChannelSourceHandle GetReadChannelSource(CancellationToken cancellationToken) + { + ThrowIfDisposed(); + return _reference.Instance.GetReadChannelSource(cancellationToken); + } + + /// + public Task GetReadChannelSourceAsync(CancellationToken cancellationToken) + { + ThrowIfDisposed(); + return _reference.Instance.GetReadChannelSourceAsync(cancellationToken); + } + /// - public IChannelSourceHandle GetReadChannelSource(CancellationToken cancellationToken, IReadOnlyCollection deprioritizedServers = null) + public IChannelSourceHandle GetReadChannelSource(IReadOnlyCollection deprioritizedServers, CancellationToken cancellationToken) { ThrowIfDisposed(); - return _reference.Instance.GetReadChannelSource(cancellationToken, deprioritizedServers); + return _reference.Instance.GetReadChannelSource(deprioritizedServers, cancellationToken); } /// - public Task GetReadChannelSourceAsync(CancellationToken cancellationToken, IReadOnlyCollection deprioritizedServers = null) + public Task GetReadChannelSourceAsync(IReadOnlyCollection deprioritizedServers, CancellationToken cancellationToken) + { + ThrowIfDisposed(); + return _reference.Instance.GetReadChannelSourceAsync(deprioritizedServers, cancellationToken); + } + + /// + public IChannelSourceHandle GetWriteChannelSource(CancellationToken cancellationToken) { ThrowIfDisposed(); - return _reference.Instance.GetReadChannelSourceAsync(cancellationToken, deprioritizedServers); + return _reference.Instance.GetWriteChannelSource(cancellationToken); } /// - public IChannelSourceHandle GetWriteChannelSource(CancellationToken cancellationToken, IReadOnlyCollection deprioritizedServers = null) + public IChannelSourceHandle GetWriteChannelSource(IReadOnlyCollection deprioritizedServers, CancellationToken cancellationToken) { ThrowIfDisposed(); - return _reference.Instance.GetWriteChannelSource(cancellationToken, deprioritizedServers); + return _reference.Instance.GetWriteChannelSource(deprioritizedServers, cancellationToken); + } + + /// + public IChannelSourceHandle GetWriteChannelSource(IMayUseSecondaryCriteria mayUseSecondary, CancellationToken cancellationToken) + { + ThrowIfDisposed(); + return _reference.Instance.GetWriteChannelSource(mayUseSecondary, cancellationToken); } /// - public IChannelSourceHandle GetWriteChannelSource(IMayUseSecondaryCriteria mayUseSecondary, CancellationToken cancellationToken, IReadOnlyCollection deprioritizedServers = null) + public IChannelSourceHandle GetWriteChannelSource(IReadOnlyCollection deprioritizedServers, IMayUseSecondaryCriteria mayUseSecondary, CancellationToken cancellationToken) { ThrowIfDisposed(); - return _reference.Instance.GetWriteChannelSource(mayUseSecondary, cancellationToken, deprioritizedServers); + return _reference.Instance.GetWriteChannelSource(deprioritizedServers, mayUseSecondary, cancellationToken); + } + + /// + public Task GetWriteChannelSourceAsync(CancellationToken cancellationToken) + { + ThrowIfDisposed(); + return _reference.Instance.GetWriteChannelSourceAsync(cancellationToken); } /// - public Task GetWriteChannelSourceAsync(CancellationToken cancellationToken, IReadOnlyCollection deprioritizedServers = null) + public Task GetWriteChannelSourceAsync(IReadOnlyCollection deprioritizedServers, CancellationToken cancellationToken) + { + ThrowIfDisposed(); + return _reference.Instance.GetWriteChannelSourceAsync(deprioritizedServers, cancellationToken); + } + + /// + public Task GetWriteChannelSourceAsync(IMayUseSecondaryCriteria mayUseSecondary, CancellationToken cancellationToken) { ThrowIfDisposed(); - return _reference.Instance.GetWriteChannelSourceAsync(cancellationToken, deprioritizedServers); + return _reference.Instance.GetWriteChannelSourceAsync(mayUseSecondary, cancellationToken); } /// - public Task GetWriteChannelSourceAsync(IMayUseSecondaryCriteria mayUseSecondary, CancellationToken cancellationToken, IReadOnlyCollection deprioritizedServers = null) + public Task GetWriteChannelSourceAsync(IReadOnlyCollection deprioritizedServers, IMayUseSecondaryCriteria mayUseSecondary, CancellationToken cancellationToken) { ThrowIfDisposed(); - return _reference.Instance.GetWriteChannelSourceAsync(mayUseSecondary, cancellationToken, deprioritizedServers); + return _reference.Instance.GetWriteChannelSourceAsync(deprioritizedServers, mayUseSecondary, cancellationToken); } /// diff --git a/src/MongoDB.Driver.Core/Core/Bindings/SingleServerReadBinding.cs b/src/MongoDB.Driver.Core/Core/Bindings/SingleServerReadBinding.cs index 28cb59c095c..7666ef3e719 100644 --- a/src/MongoDB.Driver.Core/Core/Bindings/SingleServerReadBinding.cs +++ b/src/MongoDB.Driver.Core/Core/Bindings/SingleServerReadBinding.cs @@ -64,20 +64,32 @@ public ICoreSessionHandle Session } // methods - /// - public IChannelSourceHandle GetReadChannelSource(CancellationToken cancellationToken, IReadOnlyCollection deprioritizedServers = null) + /// + public IChannelSourceHandle GetReadChannelSource(CancellationToken cancellationToken) { ThrowIfDisposed(); return GetChannelSourceHelper(); } - /// - public Task GetReadChannelSourceAsync(CancellationToken cancellationToken, IReadOnlyCollection deprioritizedServers = null) + /// + public Task GetReadChannelSourceAsync(CancellationToken cancellationToken) { ThrowIfDisposed(); return Task.FromResult(GetChannelSourceHelper()); } + /// + public IChannelSourceHandle GetReadChannelSource(IReadOnlyCollection deprioritizedServers, CancellationToken cancellationToken) + { + return GetReadChannelSource(cancellationToken); + } + + /// + public Task GetReadChannelSourceAsync(IReadOnlyCollection deprioritizedServers, CancellationToken cancellationToken) + { + return GetReadChannelSourceAsync(cancellationToken); + } + /// public void Dispose() { diff --git a/src/MongoDB.Driver.Core/Core/Bindings/SingleServerReadWriteBinding.cs b/src/MongoDB.Driver.Core/Core/Bindings/SingleServerReadWriteBinding.cs index ec849cde1f2..8fec85d3249 100644 --- a/src/MongoDB.Driver.Core/Core/Bindings/SingleServerReadWriteBinding.cs +++ b/src/MongoDB.Driver.Core/Core/Bindings/SingleServerReadWriteBinding.cs @@ -68,44 +68,80 @@ public void Dispose() } } - /// - public IChannelSourceHandle GetReadChannelSource(CancellationToken cancellationToken, IReadOnlyCollection deprioritizedServers = null) + /// + public IChannelSourceHandle GetReadChannelSource(CancellationToken cancellationToken) { ThrowIfDisposed(); return GetChannelSourceHelper(); } - /// - public Task GetReadChannelSourceAsync(CancellationToken cancellationToken, IReadOnlyCollection deprioritizedServers = null) + /// + public Task GetReadChannelSourceAsync(CancellationToken cancellationToken) { ThrowIfDisposed(); return Task.FromResult(GetChannelSourceHelper()); } /// - public IChannelSourceHandle GetWriteChannelSource(CancellationToken cancellationToken, IReadOnlyCollection deprioritizedServers = null) + public IChannelSourceHandle GetReadChannelSource(IReadOnlyCollection deprioritizedServers, CancellationToken cancellationToken) + { + return GetReadChannelSource(cancellationToken); + } + + /// + public Task GetReadChannelSourceAsync(IReadOnlyCollection deprioritizedServers, CancellationToken cancellationToken) + { + return GetReadChannelSourceAsync(cancellationToken); + } + + /// + public IChannelSourceHandle GetWriteChannelSource(CancellationToken cancellationToken) { ThrowIfDisposed(); return GetChannelSourceHelper(); } /// - public IChannelSourceHandle GetWriteChannelSource(IMayUseSecondaryCriteria mayUseSecondary, CancellationToken cancellationToken, IReadOnlyCollection deprioritizedServers = null) + public IChannelSourceHandle GetWriteChannelSource(IReadOnlyCollection deprioritizedServers, CancellationToken cancellationToken) + { + return GetWriteChannelSource(cancellationToken); + } + + /// + public IChannelSourceHandle GetWriteChannelSource(IMayUseSecondaryCriteria mayUseSecondary, CancellationToken cancellationToken) { - return GetWriteChannelSource(cancellationToken, deprioritizedServers); // ignore mayUseSecondary + return GetWriteChannelSource(cancellationToken); // ignore mayUseSecondary } /// - public Task GetWriteChannelSourceAsync(CancellationToken cancellationToken, IReadOnlyCollection deprioritizedServers = null) + public IChannelSourceHandle GetWriteChannelSource(IReadOnlyCollection deprioritizedServers, IMayUseSecondaryCriteria mayUseSecondary, CancellationToken cancellationToken) + { + return GetWriteChannelSource(mayUseSecondary, cancellationToken); + } + + /// + public Task GetWriteChannelSourceAsync(CancellationToken cancellationToken) { ThrowIfDisposed(); return Task.FromResult(GetChannelSourceHelper()); } /// - public Task GetWriteChannelSourceAsync(IMayUseSecondaryCriteria mayUseSecondary, CancellationToken cancellationToken, IReadOnlyCollection deprioritizedServers = null) + public Task GetWriteChannelSourceAsync(IReadOnlyCollection deprioritizedServers, CancellationToken cancellationToken) + { + return GetWriteChannelSourceAsync(cancellationToken); + } + + /// + public Task GetWriteChannelSourceAsync(IMayUseSecondaryCriteria mayUseSecondary, CancellationToken cancellationToken) + { + return GetWriteChannelSourceAsync(cancellationToken); // ignore mayUseSecondary + } + + /// + public Task GetWriteChannelSourceAsync(IReadOnlyCollection deprioritizedServers, IMayUseSecondaryCriteria mayUseSecondary, CancellationToken cancellationToken) { - return GetWriteChannelSourceAsync(cancellationToken, deprioritizedServers); // ignore mayUseSecondary + return GetWriteChannelSourceAsync(mayUseSecondary, cancellationToken); } private IChannelSourceHandle GetChannelSourceHelper() diff --git a/src/MongoDB.Driver.Core/Core/Bindings/WritableServerBinding.cs b/src/MongoDB.Driver.Core/Core/Bindings/WritableServerBinding.cs index 52d28a61914..379adc02944 100644 --- a/src/MongoDB.Driver.Core/Core/Bindings/WritableServerBinding.cs +++ b/src/MongoDB.Driver.Core/Core/Bindings/WritableServerBinding.cs @@ -60,8 +60,20 @@ public ICoreSessionHandle Session } // methods + /// + public IChannelSourceHandle GetReadChannelSource(CancellationToken cancellationToken) + { + return GetReadChannelSource(null, cancellationToken); + } + + /// + public async Task GetReadChannelSourceAsync(CancellationToken cancellationToken) + { + return await GetReadChannelSourceAsync(null, cancellationToken).ConfigureAwait(false); + } + /// - public IChannelSourceHandle GetReadChannelSource(CancellationToken cancellationToken, IReadOnlyCollection deprioritizedServers = null) + public IChannelSourceHandle GetReadChannelSource(IReadOnlyCollection deprioritizedServers, CancellationToken cancellationToken) { ThrowIfDisposed(); var server = _cluster.SelectServerAndPinIfNeeded(_session, WritableServerSelector.Instance, deprioritizedServers, cancellationToken); @@ -69,23 +81,35 @@ public IChannelSourceHandle GetReadChannelSource(CancellationToken cancellationT } /// - public async Task GetReadChannelSourceAsync(CancellationToken cancellationToken, IReadOnlyCollection deprioritizedServers = null) + public async Task GetReadChannelSourceAsync(IReadOnlyCollection deprioritizedServers, CancellationToken cancellationToken) { ThrowIfDisposed(); var server = await _cluster.SelectServerAndPinIfNeededAsync(_session, WritableServerSelector.Instance, deprioritizedServers, cancellationToken).ConfigureAwait(false); return CreateServerChannelSource(server); } + /// + public IChannelSourceHandle GetWriteChannelSource(CancellationToken cancellationToken) + { + return GetWriteChannelSource(deprioritizedServers: null, cancellationToken); + } + /// - public IChannelSourceHandle GetWriteChannelSource(CancellationToken cancellationToken, IReadOnlyCollection deprioritizedServers = null) + public IChannelSourceHandle GetWriteChannelSource(IReadOnlyCollection deprioritizedServers, CancellationToken cancellationToken) { ThrowIfDisposed(); var server = _cluster.SelectServerAndPinIfNeeded(_session, WritableServerSelector.Instance, deprioritizedServers, cancellationToken); return CreateServerChannelSource(server); } + /// + public IChannelSourceHandle GetWriteChannelSource(IMayUseSecondaryCriteria mayUseSecondary, CancellationToken cancellationToken) + { + return GetWriteChannelSource(null, mayUseSecondary, cancellationToken); + } + /// - public IChannelSourceHandle GetWriteChannelSource(IMayUseSecondaryCriteria mayUseSecondary, CancellationToken cancellationToken, IReadOnlyCollection deprioritizedServers = null) + public IChannelSourceHandle GetWriteChannelSource(IReadOnlyCollection deprioritizedServers, IMayUseSecondaryCriteria mayUseSecondary, CancellationToken cancellationToken) { if (IsSessionPinnedToServer()) { @@ -97,16 +121,28 @@ public IChannelSourceHandle GetWriteChannelSource(IMayUseSecondaryCriteria mayUs return CreateServerChannelSource(server); } + /// + public async Task GetWriteChannelSourceAsync(CancellationToken cancellationToken) + { + return await GetWriteChannelSourceAsync(deprioritizedServers: null, cancellationToken).ConfigureAwait(false); + } + /// - public async Task GetWriteChannelSourceAsync(CancellationToken cancellationToken, IReadOnlyCollection deprioritizedServers = null) + public async Task GetWriteChannelSourceAsync(IReadOnlyCollection deprioritizedServers, CancellationToken cancellationToken) { ThrowIfDisposed(); var server = await _cluster.SelectServerAndPinIfNeededAsync(_session, WritableServerSelector.Instance, deprioritizedServers, cancellationToken).ConfigureAwait(false); return CreateServerChannelSource(server); } + /// + public async Task GetWriteChannelSourceAsync(IMayUseSecondaryCriteria mayUseSecondary, CancellationToken cancellationToken) + { + return await GetWriteChannelSourceAsync(null, mayUseSecondary, cancellationToken).ConfigureAwait(false); + } + /// - public async Task GetWriteChannelSourceAsync(IMayUseSecondaryCriteria mayUseSecondary, CancellationToken cancellationToken, IReadOnlyCollection deprioritizedServers = null) + public async Task GetWriteChannelSourceAsync(IReadOnlyCollection deprioritizedServers, IMayUseSecondaryCriteria mayUseSecondary, CancellationToken cancellationToken) { if (IsSessionPinnedToServer()) { diff --git a/src/MongoDB.Driver.Core/Core/Operations/RetryableReadOperationExecutor.cs b/src/MongoDB.Driver.Core/Core/Operations/RetryableReadOperationExecutor.cs index d460aa73f74..cebcdf594a1 100644 --- a/src/MongoDB.Driver.Core/Core/Operations/RetryableReadOperationExecutor.cs +++ b/src/MongoDB.Driver.Core/Core/Operations/RetryableReadOperationExecutor.cs @@ -51,7 +51,7 @@ public static TResult Execute(IRetryableReadOperation operatio try { - context.ReplaceChannelSource(context.Binding.GetReadChannelSource(cancellationToken, new [] { context.ChannelSource.ServerDescription })); + context.ReplaceChannelSource(context.Binding.GetReadChannelSource(new []{ context.ChannelSource.ServerDescription }, cancellationToken)); context.ReplaceChannel(context.ChannelSource.GetChannel(cancellationToken)); } catch @@ -96,7 +96,7 @@ public static async Task ExecuteAsync(IRetryableReadOperation< try { - context.ReplaceChannelSource(context.Binding.GetReadChannelSource(cancellationToken, new [] { context.ChannelSource.ServerDescription })); + context.ReplaceChannelSource(context.Binding.GetReadChannelSource(new []{ context.ChannelSource.ServerDescription }, cancellationToken)); context.ReplaceChannel(context.ChannelSource.GetChannel(cancellationToken)); } catch diff --git a/src/MongoDB.Driver.Core/Core/Operations/RetryableWriteOperationExecutor.cs b/src/MongoDB.Driver.Core/Core/Operations/RetryableWriteOperationExecutor.cs index 6f7ff56b974..edb59aec00a 100644 --- a/src/MongoDB.Driver.Core/Core/Operations/RetryableWriteOperationExecutor.cs +++ b/src/MongoDB.Driver.Core/Core/Operations/RetryableWriteOperationExecutor.cs @@ -53,7 +53,7 @@ public static TResult Execute(IRetryableWriteOperation operati try { - context.ReplaceChannelSource(context.Binding.GetWriteChannelSource(cancellationToken, new [] { context.ChannelSource.ServerDescription })); + context.ReplaceChannelSource(context.Binding.GetWriteChannelSource(new []{ context.ChannelSource.ServerDescription }, cancellationToken)); context.ReplaceChannel(context.ChannelSource.GetChannel(cancellationToken)); } catch @@ -104,7 +104,7 @@ public static async Task ExecuteAsync(IRetryableWriteOperation try { - context.ReplaceChannelSource(await context.Binding.GetWriteChannelSourceAsync(cancellationToken, new [] { context.ChannelSource.ServerDescription }).ConfigureAwait(false)); + context.ReplaceChannelSource(await context.Binding.GetWriteChannelSourceAsync(new []{ context.ChannelSource.ServerDescription }, cancellationToken).ConfigureAwait(false)); context.ReplaceChannel(await context.ChannelSource.GetChannelAsync(cancellationToken).ConfigureAwait(false)); } catch diff --git a/tests/MongoDB.Driver.Core.Tests/Core/Bindings/ReadBindingHandleTests.cs b/tests/MongoDB.Driver.Core.Tests/Core/Bindings/ReadBindingHandleTests.cs index 2a089a050b2..d26b05ff749 100644 --- a/tests/MongoDB.Driver.Core.Tests/Core/Bindings/ReadBindingHandleTests.cs +++ b/tests/MongoDB.Driver.Core.Tests/Core/Bindings/ReadBindingHandleTests.cs @@ -83,13 +83,13 @@ public void GetReadChannelSource_should_delegate_to_reference( { subject.GetReadChannelSourceAsync(CancellationToken.None).GetAwaiter().GetResult(); - _mockReadBinding.Verify(b => b.GetReadChannelSourceAsync(CancellationToken.None, null), Times.Once); + _mockReadBinding.Verify(b => b.GetReadChannelSourceAsync(CancellationToken.None), Times.Once); } else { subject.GetReadChannelSource(CancellationToken.None); - _mockReadBinding.Verify(b => b.GetReadChannelSource(CancellationToken.None, null), Times.Once); + _mockReadBinding.Verify(b => b.GetReadChannelSource(CancellationToken.None), Times.Once); } } diff --git a/tests/MongoDB.Driver.Core.Tests/Core/Bindings/ReadWriteBindingHandleTests.cs b/tests/MongoDB.Driver.Core.Tests/Core/Bindings/ReadWriteBindingHandleTests.cs index f5d7fb7dded..33f36397c1b 100644 --- a/tests/MongoDB.Driver.Core.Tests/Core/Bindings/ReadWriteBindingHandleTests.cs +++ b/tests/MongoDB.Driver.Core.Tests/Core/Bindings/ReadWriteBindingHandleTests.cs @@ -84,13 +84,13 @@ public void GetReadChannelSource_should_delegate_to_reference( { subject.GetReadChannelSourceAsync(CancellationToken.None).GetAwaiter().GetResult(); - _mockReadWriteBinding.Verify(b => b.GetReadChannelSourceAsync(CancellationToken.None, null), Times.Once); + _mockReadWriteBinding.Verify(b => b.GetReadChannelSourceAsync(CancellationToken.None), Times.Once); } else { subject.GetReadChannelSource(CancellationToken.None); - _mockReadWriteBinding.Verify(b => b.GetReadChannelSource(CancellationToken.None, null), Times.Once); + _mockReadWriteBinding.Verify(b => b.GetReadChannelSource(CancellationToken.None), Times.Once); } } @@ -128,13 +128,13 @@ public void GetWriteChannelSource_should_delegate_to_reference( { subject.GetWriteChannelSourceAsync(CancellationToken.None).GetAwaiter().GetResult(); - _mockReadWriteBinding.Verify(b => b.GetWriteChannelSourceAsync(CancellationToken.None, null), Times.Once); + _mockReadWriteBinding.Verify(b => b.GetWriteChannelSourceAsync(CancellationToken.None), Times.Once); } else { subject.GetWriteChannelSource(CancellationToken.None); - _mockReadWriteBinding.Verify(b => b.GetWriteChannelSource(CancellationToken.None, null), Times.Once); + _mockReadWriteBinding.Verify(b => b.GetWriteChannelSource(CancellationToken.None), Times.Once); } } diff --git a/tests/MongoDB.Driver.Core.Tests/Core/Clusters/ClusterTests.cs b/tests/MongoDB.Driver.Core.Tests/Core/Clusters/ClusterTests.cs index ce0d71c8f96..e00fb4f66e7 100644 --- a/tests/MongoDB.Driver.Core.Tests/Core/Clusters/ClusterTests.cs +++ b/tests/MongoDB.Driver.Core.Tests/Core/Clusters/ClusterTests.cs @@ -415,7 +415,7 @@ public void SelectServer_should_keep_trying_to_match_by_waiting_on_cluster_descr [Theory] [ParameterAttributeData] - public async void SelectServer_should_ignore_deprioritized_servers_if_cluster_is_sharded( + public void SelectServer_should_ignore_deprioritized_servers_if_cluster_is_sharded( [Values(false, true)] bool async) { @@ -436,7 +436,6 @@ public async void SelectServer_should_ignore_deprioritized_servers_if_cluster_is var selector = new DelegateServerSelector((c, s) => s); var deprioritizedServers = new List { connected1 }; - var deprioritizedServersEndpoints = deprioritizedServers.Select(description => description.EndPoint).ToList(); for (int i = 0; i < 15; i++) { @@ -445,7 +444,7 @@ public async void SelectServer_should_ignore_deprioritized_servers_if_cluster_is IServer result; if (async) { - result = await subject.SelectServerAsync(selector, deprioritizedServers, CancellationToken.None); + result = subject.SelectServerAsync(selector, deprioritizedServers, CancellationToken.None).GetAwaiter().GetResult(); } else { @@ -453,6 +452,8 @@ public async void SelectServer_should_ignore_deprioritized_servers_if_cluster_is } result.Should().NotBeNull(); + + var deprioritizedServersEndpoints = deprioritizedServers.Select(description => description.EndPoint); deprioritizedServersEndpoints.Should().NotContain(result.Description.EndPoint); _capturedEvents.Next().Should().BeOfType(); @@ -463,51 +464,12 @@ public async void SelectServer_should_ignore_deprioritized_servers_if_cluster_is [Theory] [ParameterAttributeData] - public async void SelectServer_should_not_deprioritize_if_there_no_servers_to_deprioritize( - [Values(false, true)] bool async) - { -#pragma warning disable CS0618 // Type or member is obsolete - var subject = CreateSubject(ClusterConnectionMode.Sharded); -#pragma warning restore CS0618 // Type or member is obsolete - - subject.Initialize(); - - var endPoint1 = new DnsEndPoint("localhost", 27017); - var connected1 = ServerDescriptionHelper.Connected(subject.Description.ClusterId, endPoint1); - - subject.SetServerDescriptions(connected1); - - var selector = new DelegateServerSelector((c, s) => s); - - _capturedEvents.Clear(); - - IServer result; - if (async) - { - result = await subject.SelectServerAsync(selector, null, CancellationToken.None); - } - else - { - result = subject.SelectServer(selector, null, CancellationToken.None); - } - - result.Should().NotBeNull(); - result.EndPoint.Should().Be(endPoint1); - Logs.Count(log => log.Category == "MongoDB.ServerSelection" && log.Message.StartsWith("Deprioritization")).Should().Be(0); - - _capturedEvents.Next().Should().BeOfType(); - _capturedEvents.Next().Should().BeOfType(); - _capturedEvents.Any().Should().BeFalse(); - } - - [Theory] - [ParameterAttributeData] - public async void SelectServer_should_return_deprioritized_servers_if_no_other_servers_exist_or_cluster_not_sharded( + public void SelectServer_should_return_deprioritized_servers_if_no_other_servers_exist_or_cluster_not_sharded( [Values(false, true)] bool async, - [Values(false, true)] bool isSharded) + [Values(false, true)] bool IsSharded) { #pragma warning disable CS0618 // Type or member is obsolete - StubCluster subject = isSharded ? CreateSubject(ClusterConnectionMode.Sharded) : CreateSubject(); + StubCluster subject = IsSharded ? CreateSubject(ClusterConnectionMode.Sharded) : CreateSubject(); #pragma warning restore CS0618 // Type or member is obsolete subject.Initialize(); @@ -521,7 +483,6 @@ public async void SelectServer_should_return_deprioritized_servers_if_no_other_s var selector = new DelegateServerSelector((c, s) => s); var deprioritizedServers = new List { connected1, connected2 }; - var deprioritizedServersEndpoints = deprioritizedServers.Select(description => description.EndPoint).ToList(); for (int i = 0; i < 15; i++) { @@ -529,7 +490,7 @@ public async void SelectServer_should_return_deprioritized_servers_if_no_other_s IServer result; if (async) { - result = await subject.SelectServerAsync(selector, deprioritizedServers, CancellationToken.None); + result = subject.SelectServerAsync(selector, deprioritizedServers, CancellationToken.None).GetAwaiter().GetResult(); } else { @@ -537,6 +498,8 @@ public async void SelectServer_should_return_deprioritized_servers_if_no_other_s } result.Should().NotBeNull(); + + var deprioritizedServersEndpoints = deprioritizedServers.Select(description => description.EndPoint); deprioritizedServersEndpoints.Should().Contain(result.Description.EndPoint); _capturedEvents.Next().Should().BeOfType(); diff --git a/tests/MongoDB.Driver.Core.Tests/Core/Operations/ReadCommandOperationTests.cs b/tests/MongoDB.Driver.Core.Tests/Core/Operations/ReadCommandOperationTests.cs index 71b9a18e4b4..e66a2fa67d1 100644 --- a/tests/MongoDB.Driver.Core.Tests/Core/Operations/ReadCommandOperationTests.cs +++ b/tests/MongoDB.Driver.Core.Tests/Core/Operations/ReadCommandOperationTests.cs @@ -348,8 +348,8 @@ private Mock CreateMockReadBinding(ReadPreference readPreference, var mockSession = new Mock(); mockBinding.SetupGet(b => b.ReadPreference).Returns(readPreference); mockBinding.SetupGet(b => b.Session).Returns(mockSession.Object); - mockBinding.Setup(b => b.GetReadChannelSource(It.IsAny(), null)).Returns(channelSource); - mockBinding.Setup(b => b.GetReadChannelSourceAsync(It.IsAny(), null)).Returns(Task.FromResult(channelSource)); + mockBinding.Setup(b => b.GetReadChannelSource(It.IsAny())).Returns(channelSource); + mockBinding.Setup(b => b.GetReadChannelSourceAsync(It.IsAny())).Returns(Task.FromResult(channelSource)); return mockBinding; } diff --git a/tests/MongoDB.Driver.Core.Tests/Core/Operations/RetryableWriteOperationExecutorTests.cs b/tests/MongoDB.Driver.Core.Tests/Core/Operations/RetryableWriteOperationExecutorTests.cs index e95092a0681..9d7fd2f7f3b 100644 --- a/tests/MongoDB.Driver.Core.Tests/Core/Operations/RetryableWriteOperationExecutorTests.cs +++ b/tests/MongoDB.Driver.Core.Tests/Core/Operations/RetryableWriteOperationExecutorTests.cs @@ -98,7 +98,7 @@ private IWriteBinding CreateBinding(bool areRetryableWritesSupported, bool hasSe var session = CreateSession(hasSessionId, isInTransaction); var channelSource = CreateChannelSource(areRetryableWritesSupported); mockBinding.SetupGet(m => m.Session).Returns(session); - mockBinding.Setup(m => m.GetWriteChannelSource(CancellationToken.None, null)).Returns(channelSource); + mockBinding.Setup(m => m.GetWriteChannelSource(CancellationToken.None)).Returns(channelSource); return mockBinding.Object; } diff --git a/tests/MongoDB.Driver.Core.Tests/Core/Operations/WriteCommandOperationTests.cs b/tests/MongoDB.Driver.Core.Tests/Core/Operations/WriteCommandOperationTests.cs index 88135324973..6da9926706f 100644 --- a/tests/MongoDB.Driver.Core.Tests/Core/Operations/WriteCommandOperationTests.cs +++ b/tests/MongoDB.Driver.Core.Tests/Core/Operations/WriteCommandOperationTests.cs @@ -233,8 +233,8 @@ private Mock CreateMockWriteBinding(IChannelSourceHandle channelS var mockBinding = new Mock(); var mockSession = new Mock(); mockBinding.SetupGet(b => b.Session).Returns(mockSession.Object); - mockBinding.Setup(b => b.GetWriteChannelSource(It.IsAny(), null)).Returns(channelSource); - mockBinding.Setup(b => b.GetWriteChannelSourceAsync(It.IsAny(), null)).Returns(Task.FromResult(channelSource)); + mockBinding.Setup(b => b.GetWriteChannelSource(It.IsAny())).Returns(channelSource); + mockBinding.Setup(b => b.GetWriteChannelSourceAsync(It.IsAny())).Returns(Task.FromResult(channelSource)); return mockBinding; } From 883d0a7166193c7e6428743537b28308201d5ffb Mon Sep 17 00:00:00 2001 From: adelinowona Date: Wed, 22 May 2024 15:44:32 -0400 Subject: [PATCH 15/24] Use ServerSelector Pattern --- .../Core/Bindings/WritableServerBinding.cs | 18 +++-- .../Core/Clusters/Cluster.cs | 64 ++---------------- .../Core/Clusters/ICluster.cs | 18 ----- .../Core/Clusters/IClusterExtensions.cs | 12 +++- .../ServerSelectors/PriorityServerSelector.cs | 59 +++++++++++++++++ .../Bindings/CoreServerSessionPoolTests.cs | 2 - .../Bindings/ReadPreferenceBindingTests.cs | 12 ++-- .../Bindings/WritableServerBindingTests.cs | 65 +++++++++++++++---- .../Core/Clusters/ClusterTests.cs | 33 +++++----- .../Encryption/ClientEncryptionTests.cs | 8 +-- .../RetryableReadsProseTests.cs | 8 --- 11 files changed, 166 insertions(+), 133 deletions(-) create mode 100644 src/MongoDB.Driver.Core/Core/Clusters/ServerSelectors/PriorityServerSelector.cs diff --git a/src/MongoDB.Driver.Core/Core/Bindings/WritableServerBinding.cs b/src/MongoDB.Driver.Core/Core/Bindings/WritableServerBinding.cs index 379adc02944..676f2379f4f 100644 --- a/src/MongoDB.Driver.Core/Core/Bindings/WritableServerBinding.cs +++ b/src/MongoDB.Driver.Core/Core/Bindings/WritableServerBinding.cs @@ -116,8 +116,13 @@ public IChannelSourceHandle GetWriteChannelSource(IReadOnlyCollection GetWriteChannelSourceAsync(IReadOnlyColl throw new InvalidOperationException($"This overload of {nameof(GetWriteChannelSource)} cannot be called when pinned to a server."); } - var selector = new WritableServerSelector(mayUseSecondary); - var server = await _cluster.SelectServerAsync(selector, deprioritizedServers, cancellationToken).ConfigureAwait(false); + var writableServerSelector = new WritableServerSelector(mayUseSecondary); + + var selector = deprioritizedServers != null + ? (IServerSelector)new CompositeServerSelector(new IServerSelector[] { new PriorityServerSelector(deprioritizedServers), writableServerSelector }) + : writableServerSelector; + + var server = await _cluster.SelectServerAsync(selector, cancellationToken).ConfigureAwait(false); return CreateServerChannelSource(server); } diff --git a/src/MongoDB.Driver.Core/Core/Clusters/Cluster.cs b/src/MongoDB.Driver.Core/Core/Clusters/Cluster.cs index ec6f008c797..14304be0297 100644 --- a/src/MongoDB.Driver.Core/Core/Clusters/Cluster.cs +++ b/src/MongoDB.Driver.Core/Core/Clusters/Cluster.cs @@ -281,16 +281,6 @@ protected void OnDescriptionChanged(ClusterDescription oldDescription, ClusterDe } public IServer SelectServer(IServerSelector selector, CancellationToken cancellationToken) - { - return SelectServer(selector, null, cancellationToken); - } - - public Task SelectServerAsync(IServerSelector selector, CancellationToken cancellationToken) - { - return SelectServerAsync(selector, null, cancellationToken); - } - - public IServer SelectServer(IServerSelector selector, IReadOnlyCollection deprioritizedServers, CancellationToken cancellationToken) { ThrowIfDisposedOrNotOpen(); Ensure.IsNotNull(selector, nameof(selector)); @@ -301,7 +291,7 @@ public IServer SelectServer(IServerSelector selector, IReadOnlyCollection SelectServerAsync(IServerSelector selector, IReadOnlyCollection deprioritizedServers, CancellationToken cancellationToken) + public async Task SelectServerAsync(IServerSelector selector, CancellationToken cancellationToken) { ThrowIfDisposedOrNotOpen(); Ensure.IsNotNull(selector, nameof(selector)); @@ -330,7 +320,7 @@ public async Task SelectServerAsync(IServerSelector selector, IReadOnly { while (true) { - var server = helper.SelectServer(deprioritizedServers); + var server = helper.SelectServer(); if (server != null) { return server; @@ -493,7 +483,7 @@ public void HandleException(Exception exception) EventContext.OperationName)); } - public IServer SelectServer(IReadOnlyCollection deprioritizedServers) + public IServer SelectServer() { lock (_cluster._descriptionLock) { @@ -516,13 +506,7 @@ public IServer SelectServer(IReadOnlyCollection deprioritized _connectedServers.Clear(); _connectedServerDescriptions.Clear(); - var excludingDeprioritizedServers = deprioritizedServers?.Any() == true && _cluster.Description.Type == ClusterType.Sharded; - - var filteredServers = excludingDeprioritizedServers - ? FilterDeprioritizedServers(deprioritizedServers) - : _description.Servers; - - foreach (var description in filteredServers) + foreach (var description in _description.Servers) { if (description.State == ServerState.Connected && _cluster.TryGetServer(description.EndPoint, out var server)) @@ -600,31 +584,6 @@ private IServerSelector DecorateSelector(IServerSelector selector) return new CompositeServerSelector(allSelectors); } - - private IReadOnlyList FilterDeprioritizedServers(IReadOnlyCollection deprioritizedServers) - { - List filteredServers = new(); - foreach (var description in _description.Servers) - { - if (!deprioritizedServers.Contains(description, new ServerDescriptionComparer())) - { - filteredServers.Add(description); - } - else - { - _cluster._serverSelectionEventLogger.Logger?.LogDebug(_cluster._clusterId, - $"Deprioritization: removed server {description.ServerId}"); - } - } - - if (filteredServers.Count == 0) - { - _cluster._serverSelectionEventLogger.Logger?.LogDebug(_cluster._clusterId, "Deprioritization: reverting due to no other suitable servers"); - return _description.Servers; - } - - return filteredServers; - } } private sealed class WaitForDescriptionChangedHelper : IDisposable @@ -688,19 +647,6 @@ public void HandleCompletedTask(Task completedTask) } } - private class ServerDescriptionComparer : IEqualityComparer - { - public bool Equals(ServerDescription x, ServerDescription y) - { - return x != null && y != null && x.EndPoint == y.EndPoint; - } - - public int GetHashCode(ServerDescription obj) - { - return obj.EndPoint.GetHashCode(); - } - } - private static class State { public const int Initial = 0; diff --git a/src/MongoDB.Driver.Core/Core/Clusters/ICluster.cs b/src/MongoDB.Driver.Core/Core/Clusters/ICluster.cs index 47fcd1d4443..3b74451e22c 100644 --- a/src/MongoDB.Driver.Core/Core/Clusters/ICluster.cs +++ b/src/MongoDB.Driver.Core/Core/Clusters/ICluster.cs @@ -97,24 +97,6 @@ public interface ICluster : IDisposable /// A Task representing the operation. The result of the Task is the selected server. Task SelectServerAsync(IServerSelector selector, CancellationToken cancellationToken); - /// - /// Selects a server from the cluster while prioritizing servers not found in the provided collection of deprioritized servers. - /// - /// The server selector. - /// The deprioritized Servers. - /// The cancellation token. - /// The selected server. - IServer SelectServer(IServerSelector selector, IReadOnlyCollection deprioritizedServers, CancellationToken cancellationToken); - - /// - /// Selects a server from the cluster while prioritizing servers not found in the provided collection of deprioritized servers. - /// - /// The server selector. - /// The deprioritized Servers. - /// The cancellation token. - /// A Task representing the operation. The result of the Task is the selected server. - Task SelectServerAsync(IServerSelector selector, IReadOnlyCollection deprioritizedServers, CancellationToken cancellationToken); - /// /// Starts a session. /// diff --git a/src/MongoDB.Driver.Core/Core/Clusters/IClusterExtensions.cs b/src/MongoDB.Driver.Core/Core/Clusters/IClusterExtensions.cs index fea76186a7c..6b83a44715d 100644 --- a/src/MongoDB.Driver.Core/Core/Clusters/IClusterExtensions.cs +++ b/src/MongoDB.Driver.Core/Core/Clusters/IClusterExtensions.cs @@ -40,9 +40,13 @@ public static IServer SelectServerAndPinIfNeeded( return pinnedServer; } + selector = deprioritizedServers != null + ? new CompositeServerSelector(new[] { new PriorityServerSelector(deprioritizedServers), selector }) + : selector; + // Server selection also updates the cluster type, allowing us to to determine if the server // should be pinned. - var server = cluster.SelectServer(selector, deprioritizedServers, cancellationToken); + var server = cluster.SelectServer(selector, cancellationToken); PinServerIfNeeded(cluster, session, server); return server; } @@ -60,9 +64,13 @@ public static async Task SelectServerAndPinIfNeededAsync( return pinnedServer; } + selector = deprioritizedServers != null + ? new CompositeServerSelector(new[] { new PriorityServerSelector(deprioritizedServers), selector }) + : selector; + // Server selection also updates the cluster type, allowing us to to determine if the server // should be pinned. - var server = await cluster.SelectServerAsync(selector, deprioritizedServers, cancellationToken).ConfigureAwait(false); + var server = await cluster.SelectServerAsync(selector, cancellationToken).ConfigureAwait(false); PinServerIfNeeded(cluster, session, server); return server; diff --git a/src/MongoDB.Driver.Core/Core/Clusters/ServerSelectors/PriorityServerSelector.cs b/src/MongoDB.Driver.Core/Core/Clusters/ServerSelectors/PriorityServerSelector.cs new file mode 100644 index 00000000000..3f489536f02 --- /dev/null +++ b/src/MongoDB.Driver.Core/Core/Clusters/ServerSelectors/PriorityServerSelector.cs @@ -0,0 +1,59 @@ +/* Copyright 2010-present MongoDB Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +using System.Collections.Generic; +using System.Linq; +using MongoDB.Driver.Core.Misc; +using MongoDB.Driver.Core.Servers; + +namespace MongoDB.Driver.Core.Clusters.ServerSelectors; + +/// +/// Represents a server selector that selects servers based on a collection of servers to deprioritize. +/// +public class PriorityServerSelector : IServerSelector +{ + private readonly IReadOnlyCollection _deprioritizedServers; + + /// + /// Initializes a new instance of the class. + /// + /// The collection of servers to deprioritize. + public PriorityServerSelector(IReadOnlyCollection deprioritizedServers) + { + _deprioritizedServers = Ensure.IsNotNull(deprioritizedServers, nameof(deprioritizedServers)); + } + + /// + public IEnumerable SelectServers(ClusterDescription cluster, IEnumerable servers) + { + // according to spec, we only do deprioritization in a sharded cluster. + if (cluster.Type != ClusterType.Sharded) + { + return servers; + } + + var serversList = servers.ToList(); + var filteredServers = serversList.Where(description => _deprioritizedServers.All(d => d.EndPoint != description.EndPoint)).ToList(); + + return filteredServers.Any() ? filteredServers : serversList; + } + + /// + public override string ToString() + { + return "PriorityServerSelector"; + } +} diff --git a/tests/MongoDB.Driver.Core.Tests/Core/Bindings/CoreServerSessionPoolTests.cs b/tests/MongoDB.Driver.Core.Tests/Core/Bindings/CoreServerSessionPoolTests.cs index 0996d933304..930eb24a2af 100644 --- a/tests/MongoDB.Driver.Core.Tests/Core/Bindings/CoreServerSessionPoolTests.cs +++ b/tests/MongoDB.Driver.Core.Tests/Core/Bindings/CoreServerSessionPoolTests.cs @@ -309,8 +309,6 @@ public TestCluster(ClusterType clusterType) public void Initialize() => DescriptionChanged?.Invoke(this, new ClusterDescriptionChangedEventArgs(Description, Description)); public IServer SelectServer(IServerSelector selector, CancellationToken cancellationToken) => throw new NotImplementedException(); public Task SelectServerAsync(IServerSelector selector, CancellationToken cancellationToken) => throw new NotImplementedException(); - public IServer SelectServer(IServerSelector selector, IReadOnlyCollection deprioritizedServers, CancellationToken cancellationToken) => throw new NotImplementedException(); - public Task SelectServerAsync(IServerSelector selector, IReadOnlyCollection deprioritizedServers, CancellationToken cancellationToken) => throw new NotImplementedException(); public ICoreSessionHandle StartSession(CoreSessionOptions options = null) => throw new NotImplementedException(); } } diff --git a/tests/MongoDB.Driver.Core.Tests/Core/Bindings/ReadPreferenceBindingTests.cs b/tests/MongoDB.Driver.Core.Tests/Core/Bindings/ReadPreferenceBindingTests.cs index b523b942c83..6f6468e5dbc 100644 --- a/tests/MongoDB.Driver.Core.Tests/Core/Bindings/ReadPreferenceBindingTests.cs +++ b/tests/MongoDB.Driver.Core.Tests/Core/Bindings/ReadPreferenceBindingTests.cs @@ -119,19 +119,19 @@ public void GetReadChannelSource_should_use_a_read_preference_server_selector_to if (async) { - _mockCluster.Setup(c => c.SelectServerAsync(It.IsAny(), null, CancellationToken.None)).Returns(Task.FromResult(selectedServer)); + _mockCluster.Setup(c => c.SelectServerAsync(It.IsAny(), CancellationToken.None)).Returns(Task.FromResult(selectedServer)); subject.GetReadChannelSourceAsync(CancellationToken.None).GetAwaiter().GetResult(); - _mockCluster.Verify(c => c.SelectServerAsync(It.IsAny(), null, CancellationToken.None), Times.Once); + _mockCluster.Verify(c => c.SelectServerAsync(It.IsAny(), CancellationToken.None), Times.Once); } else { - _mockCluster.Setup(c => c.SelectServer(It.IsAny(), null, CancellationToken.None)).Returns(selectedServer); + _mockCluster.Setup(c => c.SelectServer(It.IsAny(), CancellationToken.None)).Returns(selectedServer); subject.GetReadChannelSource(CancellationToken.None); - _mockCluster.Verify(c => c.SelectServer(It.IsAny(), null, CancellationToken.None), Times.Once); + _mockCluster.Verify(c => c.SelectServer(It.IsAny(), CancellationToken.None), Times.Once); } } @@ -146,8 +146,8 @@ public void GetReadChannelSource_should_fork_the_session( var cancellationToken = cancellationTokenSource.Token; var selectedServer = new Mock().Object; - _mockCluster.Setup(m => m.SelectServer(It.IsAny(), null, cancellationToken)).Returns(selectedServer); - _mockCluster.Setup(m => m.SelectServerAsync(It.IsAny(), null, cancellationToken)).Returns(Task.FromResult(selectedServer)); + _mockCluster.Setup(m => m.SelectServer(It.IsAny(), cancellationToken)).Returns(selectedServer); + _mockCluster.Setup(m => m.SelectServerAsync(It.IsAny(), cancellationToken)).Returns(Task.FromResult(selectedServer)); var forkedSession = new Mock().Object; mockSession.Setup(m => m.Fork()).Returns(forkedSession); diff --git a/tests/MongoDB.Driver.Core.Tests/Core/Bindings/WritableServerBindingTests.cs b/tests/MongoDB.Driver.Core.Tests/Core/Bindings/WritableServerBindingTests.cs index c71e283091b..90ac2dd0cbe 100644 --- a/tests/MongoDB.Driver.Core.Tests/Core/Bindings/WritableServerBindingTests.cs +++ b/tests/MongoDB.Driver.Core.Tests/Core/Bindings/WritableServerBindingTests.cs @@ -123,19 +123,19 @@ public void GetReadChannelSource_should_use_a_writable_server_selector_to_select if (async) { - _mockCluster.Setup(c => c.SelectServerAsync(It.IsAny(), null, CancellationToken.None)).Returns(Task.FromResult(selectedServer)); + _mockCluster.Setup(c => c.SelectServerAsync(It.IsAny(), CancellationToken.None)).Returns(Task.FromResult(selectedServer)); subject.GetReadChannelSourceAsync(CancellationToken.None).GetAwaiter().GetResult(); - _mockCluster.Verify(c => c.SelectServerAsync(It.IsAny(), null, CancellationToken.None), Times.Once); + _mockCluster.Verify(c => c.SelectServerAsync(It.IsAny(), CancellationToken.None), Times.Once); } else { - _mockCluster.Setup(c => c.SelectServer(It.IsAny(), null, CancellationToken.None)).Returns(selectedServer); + _mockCluster.Setup(c => c.SelectServer(It.IsAny(), CancellationToken.None)).Returns(selectedServer); subject.GetReadChannelSource(CancellationToken.None); - _mockCluster.Verify(c => c.SelectServer(It.IsAny(), null, CancellationToken.None), Times.Once); + _mockCluster.Verify(c => c.SelectServer(It.IsAny(), CancellationToken.None), Times.Once); } } @@ -184,19 +184,60 @@ public void GetWriteChannelSourceAsync_should_use_a_writable_server_selector_to_ if (async) { - _mockCluster.Setup(c => c.SelectServerAsync(It.IsAny(), null, CancellationToken.None)).Returns(Task.FromResult(selectedServer)); + _mockCluster.Setup(c => c.SelectServerAsync(It.IsAny(), CancellationToken.None)).Returns(Task.FromResult(selectedServer)); subject.GetWriteChannelSourceAsync(CancellationToken.None).GetAwaiter().GetResult(); - _mockCluster.Verify(c => c.SelectServerAsync(It.IsAny(), null, CancellationToken.None), Times.Once); + _mockCluster.Verify(c => c.SelectServerAsync(It.IsAny(), CancellationToken.None), Times.Once); } else { - _mockCluster.Setup(c => c.SelectServer(It.IsAny(), null, CancellationToken.None)).Returns(selectedServer); + _mockCluster.Setup(c => c.SelectServer(It.IsAny(), CancellationToken.None)).Returns(selectedServer); subject.GetWriteChannelSource(CancellationToken.None); - _mockCluster.Verify(c => c.SelectServer(It.IsAny(), null, CancellationToken.None), Times.Once); + _mockCluster.Verify(c => c.SelectServer(It.IsAny(), CancellationToken.None), Times.Once); + } + } + + [Theory] + [ParameterAttributeData] + public void GetWriteChannelSource_should_use_a_composite_server_selector_to_select_the_server_from_the_cluster_when_deprioritized_servers_present( + [Values(false, true)] + bool async) + { + var subject = new WritableServerBinding(_mockCluster.Object, NoCoreSession.NewHandle()); + var selectedServer = new Mock().Object; + + var clusterId = new ClusterId(); + var endPoint = new DnsEndPoint("localhost", 27017); +#pragma warning disable CS0618 // Type or member is obsolete + var initialClusterDescription = new ClusterDescription( + clusterId, + ClusterConnectionMode.Sharded, + ClusterType.Unknown, + new[] { new ServerDescription(new ServerId(clusterId, endPoint), endPoint) }); +#pragma warning restore CS0618 // Type or member is obsolete + var finalClusterDescription = initialClusterDescription.WithType(ClusterType.Sharded); + _mockCluster.SetupSequence(c => c.Description).Returns(initialClusterDescription).Returns(finalClusterDescription); + + var deprioritizedServers = new ServerDescription[] { }; + + if (async) + { + _mockCluster.Setup(c => c.SelectServerAsync(It.Is(cp => cp.ToString().Contains("PriorityServerSelector")), CancellationToken.None)).Returns(Task.FromResult(selectedServer)); + + subject.GetWriteChannelSourceAsync(deprioritizedServers, CancellationToken.None).GetAwaiter().GetResult(); + + _mockCluster.Verify(c => c.SelectServerAsync(It.Is(cp => cp.ToString().Contains("PriorityServerSelector")), CancellationToken.None), Times.Once); + } + else + { + _mockCluster.Setup(c => c.SelectServer(It.Is(cp => cp.ToString().Contains("PriorityServerSelector")), CancellationToken.None)).Returns(selectedServer); + + subject.GetWriteChannelSource(deprioritizedServers, CancellationToken.None); + + _mockCluster.Verify(c => c.SelectServer(It.Is(c => c.ToString().Contains("PriorityServerSelector")), CancellationToken.None), Times.Once); } } @@ -228,19 +269,19 @@ public void GetWriteChannelSource_with_mayUseSecondary_should_pass_mayUseSeconda if (async) { - _mockCluster.Setup(c => c.SelectServerAsync(It.IsAny(), null, CancellationToken.None)).Returns(Task.FromResult(selectedServer)); + _mockCluster.Setup(c => c.SelectServerAsync(It.IsAny(), CancellationToken.None)).Returns(Task.FromResult(selectedServer)); subject.GetWriteChannelSourceAsync(mayUseSecondary, CancellationToken.None).GetAwaiter().GetResult(); - _mockCluster.Verify(c => c.SelectServerAsync(It.Is(s => s.MayUseSecondary == mayUseSecondary), null, CancellationToken.None), Times.Once); + _mockCluster.Verify(c => c.SelectServerAsync(It.Is(s => s.MayUseSecondary == mayUseSecondary), CancellationToken.None), Times.Once); } else { - _mockCluster.Setup(c => c.SelectServer(It.IsAny(), null, CancellationToken.None)).Returns(selectedServer); + _mockCluster.Setup(c => c.SelectServer(It.IsAny(), CancellationToken.None)).Returns(selectedServer); subject.GetWriteChannelSource(mayUseSecondary, CancellationToken.None); - _mockCluster.Verify(c => c.SelectServer(It.Is(s => s.MayUseSecondary == mayUseSecondary), null, CancellationToken.None), Times.Once); + _mockCluster.Verify(c => c.SelectServer(It.Is(s => s.MayUseSecondary == mayUseSecondary), CancellationToken.None), Times.Once); } } diff --git a/tests/MongoDB.Driver.Core.Tests/Core/Clusters/ClusterTests.cs b/tests/MongoDB.Driver.Core.Tests/Core/Clusters/ClusterTests.cs index e00fb4f66e7..83ba93e53d0 100644 --- a/tests/MongoDB.Driver.Core.Tests/Core/Clusters/ClusterTests.cs +++ b/tests/MongoDB.Driver.Core.Tests/Core/Clusters/ClusterTests.cs @@ -425,18 +425,16 @@ public void SelectServer_should_ignore_deprioritized_servers_if_cluster_is_shard subject.Initialize(); - var endPoint1 = new DnsEndPoint("localhost", 27017); - var endPoint2 = new DnsEndPoint("localhost", 27018); - var endPoint3 = new DnsEndPoint("localhost", 27019); - var connected1 = ServerDescriptionHelper.Connected(subject.Description.ClusterId, endPoint1); - var connected2 = ServerDescriptionHelper.Connected(subject.Description.ClusterId, endPoint2); - var connected3 = ServerDescriptionHelper.Connected(subject.Description.ClusterId, endPoint3); - subject.SetServerDescriptions(connected1, connected2, connected3); + var connected1 = ServerDescriptionHelper.Connected(subject.Description.ClusterId, new DnsEndPoint("localhost", 27017)); + var connected2 = ServerDescriptionHelper.Connected(subject.Description.ClusterId, new DnsEndPoint("localhost", 27018)); + var connected3 = ServerDescriptionHelper.Connected(subject.Description.ClusterId, new DnsEndPoint("localhost", 27019)); - var selector = new DelegateServerSelector((c, s) => s); + subject.SetServerDescriptions(connected1, connected2, connected3); var deprioritizedServers = new List { connected1 }; + var selector = new PriorityServerSelector(deprioritizedServers); + for (int i = 0; i < 15; i++) { _capturedEvents.Clear(); @@ -444,11 +442,11 @@ public void SelectServer_should_ignore_deprioritized_servers_if_cluster_is_shard IServer result; if (async) { - result = subject.SelectServerAsync(selector, deprioritizedServers, CancellationToken.None).GetAwaiter().GetResult(); + result = subject.SelectServerAsync(selector, CancellationToken.None).GetAwaiter().GetResult(); } else { - result = subject.SelectServer(selector, deprioritizedServers, CancellationToken.None); + result = subject.SelectServer(selector, CancellationToken.None); } result.Should().NotBeNull(); @@ -474,27 +472,26 @@ public void SelectServer_should_return_deprioritized_servers_if_no_other_servers subject.Initialize(); - var endPoint1 = new DnsEndPoint("localhost", 27017); - var endPoint2 = new DnsEndPoint("localhost", 27018); - var connected1 = ServerDescriptionHelper.Connected(subject.Description.ClusterId, endPoint1); - var connected2 = ServerDescriptionHelper.Connected(subject.Description.ClusterId, endPoint2); - subject.SetServerDescriptions(connected1, connected2); + var connected1 = ServerDescriptionHelper.Connected(subject.Description.ClusterId, new DnsEndPoint("localhost", 27017)); + var connected2 = ServerDescriptionHelper.Connected(subject.Description.ClusterId, new DnsEndPoint("localhost", 27018)); - var selector = new DelegateServerSelector((c, s) => s); + subject.SetServerDescriptions(connected1, connected2); var deprioritizedServers = new List { connected1, connected2 }; + var selector = new PriorityServerSelector(deprioritizedServers); + for (int i = 0; i < 15; i++) { _capturedEvents.Clear(); IServer result; if (async) { - result = subject.SelectServerAsync(selector, deprioritizedServers, CancellationToken.None).GetAwaiter().GetResult(); + result = subject.SelectServerAsync(selector, CancellationToken.None).GetAwaiter().GetResult(); } else { - result = subject.SelectServer(selector, deprioritizedServers, CancellationToken.None); + result = subject.SelectServer(selector, CancellationToken.None); } result.Should().NotBeNull(); diff --git a/tests/MongoDB.Driver.Tests/Encryption/ClientEncryptionTests.cs b/tests/MongoDB.Driver.Tests/Encryption/ClientEncryptionTests.cs index a5456c9952c..7126b685cb7 100644 --- a/tests/MongoDB.Driver.Tests/Encryption/ClientEncryptionTests.cs +++ b/tests/MongoDB.Driver.Tests/Encryption/ClientEncryptionTests.cs @@ -140,10 +140,10 @@ public async Task CreateEncryptedCollection_should_handle_generated_key_when_sec mockServer.Setup(s => s.GetChannelAsync(It.IsAny())).ReturnsAsync(channel); mockCluster - .Setup(m => m.SelectServer(It.IsAny(), null, It.IsAny())) + .Setup(m => m.SelectServer(It.IsAny(), It.IsAny())) .Returns(mockServer.Object); mockCluster - .Setup(m => m.SelectServerAsync(It.IsAny(), null, It.IsAny())) + .Setup(m => m.SelectServerAsync(It.IsAny(), It.IsAny())) .ReturnsAsync(mockServer.Object); var database = Mock.Of(d => @@ -229,10 +229,10 @@ public async Task CreateEncryptedCollection_should_handle_various_encryptedField mockServer.Setup(s => s.GetChannelAsync(It.IsAny())).ReturnsAsync(channel); mockCluster - .Setup(m => m.SelectServer(It.IsAny(), null, It.IsAny())) + .Setup(m => m.SelectServer(It.IsAny(), It.IsAny())) .Returns(mockServer.Object); mockCluster - .Setup(m => m.SelectServerAsync(It.IsAny(), null, It.IsAny())) + .Setup(m => m.SelectServerAsync(It.IsAny(), It.IsAny())) .ReturnsAsync(mockServer.Object); var database = Mock.Of(d => diff --git a/tests/MongoDB.Driver.Tests/Specifications/retryable-reads/RetryableReadsProseTests.cs b/tests/MongoDB.Driver.Tests/Specifications/retryable-reads/RetryableReadsProseTests.cs index f198c576268..f41b1e6c798 100644 --- a/tests/MongoDB.Driver.Tests/Specifications/retryable-reads/RetryableReadsProseTests.cs +++ b/tests/MongoDB.Driver.Tests/Specifications/retryable-reads/RetryableReadsProseTests.cs @@ -176,9 +176,6 @@ public void Sharded_cluster_retryable_reads_are_retried_on_different_mongos_if_a failedEvents[0].CommandName.Should().Be(failedEvents[1].CommandName).And.Be("find"); failedEvents[0].ConnectionId.ServerId().Should().NotBe(failedEvents[1].ConnectionId.ServerId()); - - // Assert the deprioritization debug message was emitted for deprioritized server. - Logs.Count(log => log.Category == "MongoDB.ServerSelection" && log.Message.StartsWith("Deprioritization")).Should().Be(1); } [Fact] @@ -227,11 +224,6 @@ public void Sharded_cluster_retryable_reads_are_retried_on_same_mongo_if_no_othe failedEvents[0].CommandName.Should().Be(succeededEvents[0].CommandName).And.Be("find"); failedEvents[0].ConnectionId.ServerId().Should().Be(succeededEvents[0].ConnectionId.ServerId()); - - // Assert the deprioritization debug messages were emitted - // one for deprioritizing the failpointServer and another for - // reverting the deprioritization since we have no other suitable servers in this test - Logs.Count(log => log.Category == "MongoDB.ServerSelection" && log.Message.StartsWith("Deprioritization")).Should().Be(2); } // private methods From a6a1569a0b744ec985af9291c24b2828c09e57bc Mon Sep 17 00:00:00 2001 From: adelinowona Date: Wed, 22 May 2024 17:17:21 -0400 Subject: [PATCH 16/24] Cleanup --- .../Core/Clusters/LoadBalancedCluster.cs | 8 -------- .../Core/Clusters/ClusterTests.cs | 6 ++---- .../RetryableReadsProseTests.cs | 12 +++-------- .../prose-tests/RetryWriteOnOtherMongos.cs | 20 +++---------------- 4 files changed, 8 insertions(+), 38 deletions(-) diff --git a/src/MongoDB.Driver.Core/Core/Clusters/LoadBalancedCluster.cs b/src/MongoDB.Driver.Core/Core/Clusters/LoadBalancedCluster.cs index af4e8eb9a50..14bcba657a5 100644 --- a/src/MongoDB.Driver.Core/Core/Clusters/LoadBalancedCluster.cs +++ b/src/MongoDB.Driver.Core/Core/Clusters/LoadBalancedCluster.cs @@ -256,14 +256,6 @@ public async Task SelectServerAsync(IServerSelector selector, Cancellat throw new InvalidOperationException("The server must be created before usage."); // should not be reached } - public IServer SelectServer(IServerSelector selector, IReadOnlyCollection deprioritizedServers, - CancellationToken cancellationToken) => - throw new NotImplementedException(); - - public Task SelectServerAsync(IServerSelector selector, IReadOnlyCollection deprioritizedServers, - CancellationToken cancellationToken) => - throw new NotImplementedException(); - public ICoreSessionHandle StartSession(CoreSessionOptions options = null) { ThrowIfDisposed(); diff --git a/tests/MongoDB.Driver.Core.Tests/Core/Clusters/ClusterTests.cs b/tests/MongoDB.Driver.Core.Tests/Core/Clusters/ClusterTests.cs index 83ba93e53d0..9cea5cb3370 100644 --- a/tests/MongoDB.Driver.Core.Tests/Core/Clusters/ClusterTests.cs +++ b/tests/MongoDB.Driver.Core.Tests/Core/Clusters/ClusterTests.cs @@ -451,8 +451,7 @@ public void SelectServer_should_ignore_deprioritized_servers_if_cluster_is_shard result.Should().NotBeNull(); - var deprioritizedServersEndpoints = deprioritizedServers.Select(description => description.EndPoint); - deprioritizedServersEndpoints.Should().NotContain(result.Description.EndPoint); + deprioritizedServers.Should().NotContain(d => d.EndPoint == result.Description.EndPoint); _capturedEvents.Next().Should().BeOfType(); _capturedEvents.Next().Should().BeOfType(); @@ -496,8 +495,7 @@ public void SelectServer_should_return_deprioritized_servers_if_no_other_servers result.Should().NotBeNull(); - var deprioritizedServersEndpoints = deprioritizedServers.Select(description => description.EndPoint); - deprioritizedServersEndpoints.Should().Contain(result.Description.EndPoint); + deprioritizedServers.Should().Contain(d => d.EndPoint == result.Description.EndPoint); _capturedEvents.Next().Should().BeOfType(); _capturedEvents.Next().Should().BeOfType(); diff --git a/tests/MongoDB.Driver.Tests/Specifications/retryable-reads/RetryableReadsProseTests.cs b/tests/MongoDB.Driver.Tests/Specifications/retryable-reads/RetryableReadsProseTests.cs index f41b1e6c798..4d9002d459c 100644 --- a/tests/MongoDB.Driver.Tests/Specifications/retryable-reads/RetryableReadsProseTests.cs +++ b/tests/MongoDB.Driver.Tests/Specifications/retryable-reads/RetryableReadsProseTests.cs @@ -27,22 +27,16 @@ using MongoDB.Driver.Core.Events; using MongoDB.Driver.Core.Misc; using MongoDB.Driver.Core.TestHelpers; -using MongoDB.Driver.Core.TestHelpers.Logging; using MongoDB.Driver.Core.TestHelpers.XunitExtensions; using MongoDB.Driver.TestHelpers; using MongoDB.Driver.Tests.Specifications.connection_monitoring_and_pooling; using MongoDB.TestHelpers.XunitExtensions; using Xunit; -using Xunit.Abstractions; namespace MongoDB.Driver.Tests.Specifications.retryable_reads { - public class RetryableReadsProseTests : LoggableTestClass + public class RetryableReadsProseTests { - public RetryableReadsProseTests(ITestOutputHelper output) : base(output, includeAllCategories: true) - { - } - [Theory] [ParameterAttributeData] public async Task PoolClearedError_read_retryablity_test([Values(true, false)] bool async) @@ -155,7 +149,7 @@ public void Sharded_cluster_retryable_reads_are_retried_on_different_mongos_if_a s.RetryReads = true; s.ClusterConfigurator = b => b.Subscribe(eventCapturer); } - , LoggingSettings, true); + , null, true); var failPointServer1 = client.Cluster.SelectServer(new EndPointServerSelector(client.Cluster.Description.Servers[0].EndPoint), default); var failPointServer2 = client.Cluster.SelectServer(new EndPointServerSelector(client.Cluster.Description.Servers[1].EndPoint), default); @@ -205,7 +199,7 @@ public void Sharded_cluster_retryable_reads_are_retried_on_same_mongo_if_no_othe s.DirectConnection = false; s.ClusterConfigurator = b => b.Subscribe(eventCapturer); } - , LoggingSettings); + , null); var failPointServer = client.Cluster.SelectServer(new EndPointServerSelector(client.Cluster.Description.Servers[0].EndPoint), default); diff --git a/tests/MongoDB.Driver.Tests/Specifications/retryable-writes/prose-tests/RetryWriteOnOtherMongos.cs b/tests/MongoDB.Driver.Tests/Specifications/retryable-writes/prose-tests/RetryWriteOnOtherMongos.cs index 2bddf884f17..ccf1b8207cc 100644 --- a/tests/MongoDB.Driver.Tests/Specifications/retryable-writes/prose-tests/RetryWriteOnOtherMongos.cs +++ b/tests/MongoDB.Driver.Tests/Specifications/retryable-writes/prose-tests/RetryWriteOnOtherMongos.cs @@ -23,20 +23,14 @@ using MongoDB.Driver.Core.Events; using MongoDB.Driver.Core.Misc; using MongoDB.Driver.Core.TestHelpers; -using MongoDB.Driver.Core.TestHelpers.Logging; using MongoDB.Driver.Core.TestHelpers.XunitExtensions; using MongoDB.Driver.Tests.Specifications.connection_monitoring_and_pooling; using Xunit; -using Xunit.Abstractions; namespace MongoDB.Driver.Tests.Specifications.retryable_writes.prose_tests { - public class RetryWriteOnOtherMongos : LoggableTestClass + public class RetryWriteOnOtherMongos { - public RetryWriteOnOtherMongos(ITestOutputHelper output) : base(output, includeAllCategories: true) - { - } - [Fact] public void Sharded_cluster_retryable_writes_are_retried_on_different_mongos_if_available() { @@ -65,7 +59,7 @@ public void Sharded_cluster_retryable_writes_are_retried_on_different_mongos_if_ s.RetryWrites = true; s.ClusterConfigurator = b => b.Subscribe(eventCapturer); } - , LoggingSettings, true); + , null, true); var failPointServer1 = client.Cluster.SelectServer(new EndPointServerSelector(client.Cluster.Description.Servers[0].EndPoint), default); var failPointServer2 = client.Cluster.SelectServer(new EndPointServerSelector(client.Cluster.Description.Servers[1].EndPoint), default); @@ -86,9 +80,6 @@ public void Sharded_cluster_retryable_writes_are_retried_on_different_mongos_if_ failedEvents[0].CommandName.Should().Be(failedEvents[1].CommandName).And.Be("insert"); failedEvents[0].ConnectionId.ServerId().Should().NotBe(failedEvents[1].ConnectionId.ServerId()); - - // Assert the deprioritization debug message was emitted for deprioritized server. - Logs.Count(log => log.Category == "MongoDB.ServerSelection" && log.Message.StartsWith("Deprioritization")).Should().Be(1); } [Fact] @@ -119,7 +110,7 @@ public void Sharded_cluster_retryable_writes_are_retried_on_same_mongo_if_no_oth s.DirectConnection = false; s.ClusterConfigurator = b => b.Subscribe(eventCapturer); } - , LoggingSettings); + , null); var failPointServer = client.Cluster.SelectServer(new EndPointServerSelector(client.Cluster.Description.Servers[0].EndPoint), default); @@ -138,11 +129,6 @@ public void Sharded_cluster_retryable_writes_are_retried_on_same_mongo_if_no_oth failedEvents[0].CommandName.Should().Be(succeededEvents[0].CommandName).And.Be("insert"); failedEvents[0].ConnectionId.ServerId().Should().Be(succeededEvents[0].ConnectionId.ServerId()); - - // Assert the deprioritization debug messages were emitted - // one for deprioritizing the failpointServer and another for - // reverting the deprioritization since we have no other suitable servers in this test - Logs.Count(log => log.Category == "MongoDB.ServerSelection" && log.Message.StartsWith("Deprioritization")).Should().Be(2); } } } From 8de4da261ea7afb738282b262cd132f336f0fc32 Mon Sep 17 00:00:00 2001 From: adelinowona Date: Fri, 24 May 2024 17:07:04 -0400 Subject: [PATCH 17/24] resolve review comments --- .../Core/Bindings/WritableServerBinding.cs | 4 +- .../Core/Clusters/ICluster.cs | 1 - .../ServerSelectors/PriorityServerSelector.cs | 51 +++++++++---------- .../RetryableReadOperationExecutor.cs | 4 +- .../RetryableWriteOperationExecutor.cs | 4 +- .../Bindings/WritableServerBindingTests.cs | 4 +- .../Core/Clusters/ClusterTests.cs | 41 +++++++-------- .../RetryableReadsProseTests.cs | 11 ++-- .../prose-tests/RetryWriteOnOtherMongos.cs | 11 ++-- 9 files changed, 61 insertions(+), 70 deletions(-) diff --git a/src/MongoDB.Driver.Core/Core/Bindings/WritableServerBinding.cs b/src/MongoDB.Driver.Core/Core/Bindings/WritableServerBinding.cs index 676f2379f4f..2cf1afb470b 100644 --- a/src/MongoDB.Driver.Core/Core/Bindings/WritableServerBinding.cs +++ b/src/MongoDB.Driver.Core/Core/Bindings/WritableServerBinding.cs @@ -156,8 +156,8 @@ public async Task GetWriteChannelSourceAsync(IReadOnlyColl var writableServerSelector = new WritableServerSelector(mayUseSecondary); - var selector = deprioritizedServers != null - ? (IServerSelector)new CompositeServerSelector(new IServerSelector[] { new PriorityServerSelector(deprioritizedServers), writableServerSelector }) + IServerSelector selector = deprioritizedServers != null + ? new CompositeServerSelector(new IServerSelector[] { new PriorityServerSelector(deprioritizedServers), writableServerSelector }) : writableServerSelector; var server = await _cluster.SelectServerAsync(selector, cancellationToken).ConfigureAwait(false); diff --git a/src/MongoDB.Driver.Core/Core/Clusters/ICluster.cs b/src/MongoDB.Driver.Core/Core/Clusters/ICluster.cs index 3b74451e22c..1be15c516be 100644 --- a/src/MongoDB.Driver.Core/Core/Clusters/ICluster.cs +++ b/src/MongoDB.Driver.Core/Core/Clusters/ICluster.cs @@ -14,7 +14,6 @@ */ using System; -using System.Collections.Generic; using System.Threading; using System.Threading.Tasks; using MongoDB.Driver.Core.Bindings; diff --git a/src/MongoDB.Driver.Core/Core/Clusters/ServerSelectors/PriorityServerSelector.cs b/src/MongoDB.Driver.Core/Core/Clusters/ServerSelectors/PriorityServerSelector.cs index 3f489536f02..4d99594d36f 100644 --- a/src/MongoDB.Driver.Core/Core/Clusters/ServerSelectors/PriorityServerSelector.cs +++ b/src/MongoDB.Driver.Core/Core/Clusters/ServerSelectors/PriorityServerSelector.cs @@ -18,42 +18,39 @@ using MongoDB.Driver.Core.Misc; using MongoDB.Driver.Core.Servers; -namespace MongoDB.Driver.Core.Clusters.ServerSelectors; - -/// -/// Represents a server selector that selects servers based on a collection of servers to deprioritize. -/// -public class PriorityServerSelector : IServerSelector +namespace MongoDB.Driver.Core.Clusters.ServerSelectors { - private readonly IReadOnlyCollection _deprioritizedServers; - /// - /// Initializes a new instance of the class. + /// Represents a server selector that selects servers based on a collection of servers to deprioritize. /// - /// The collection of servers to deprioritize. - public PriorityServerSelector(IReadOnlyCollection deprioritizedServers) + public sealed class PriorityServerSelector : IServerSelector { - _deprioritizedServers = Ensure.IsNotNull(deprioritizedServers, nameof(deprioritizedServers)); - } + private readonly IReadOnlyCollection _deprioritizedServers; - /// - public IEnumerable SelectServers(ClusterDescription cluster, IEnumerable servers) - { - // according to spec, we only do deprioritization in a sharded cluster. - if (cluster.Type != ClusterType.Sharded) + /// + /// Initializes a new instance of the class. + /// + /// The collection of servers to deprioritize. + public PriorityServerSelector(IReadOnlyCollection deprioritizedServers) { - return servers; + _deprioritizedServers = Ensure.IsNotNull(deprioritizedServers, nameof(deprioritizedServers)); } - var serversList = servers.ToList(); - var filteredServers = serversList.Where(description => _deprioritizedServers.All(d => d.EndPoint != description.EndPoint)).ToList(); + /// + public IEnumerable SelectServers(ClusterDescription cluster, IEnumerable servers) + { + // according to spec, we only do deprioritization in a sharded cluster. + if (cluster.Type != ClusterType.Sharded) + { + return servers; + } - return filteredServers.Any() ? filteredServers : serversList; - } + var filteredServers = servers.Where(description => _deprioritizedServers.All(d => d.EndPoint != description.EndPoint)).ToList(); - /// - public override string ToString() - { - return "PriorityServerSelector"; + return filteredServers.Any() ? filteredServers : servers; + } + + /// + public override string ToString() => "PriorityServerSelector"; } } diff --git a/src/MongoDB.Driver.Core/Core/Operations/RetryableReadOperationExecutor.cs b/src/MongoDB.Driver.Core/Core/Operations/RetryableReadOperationExecutor.cs index cebcdf594a1..1c81b572b7c 100644 --- a/src/MongoDB.Driver.Core/Core/Operations/RetryableReadOperationExecutor.cs +++ b/src/MongoDB.Driver.Core/Core/Operations/RetryableReadOperationExecutor.cs @@ -51,7 +51,7 @@ public static TResult Execute(IRetryableReadOperation operatio try { - context.ReplaceChannelSource(context.Binding.GetReadChannelSource(new []{ context.ChannelSource.ServerDescription }, cancellationToken)); + context.ReplaceChannelSource(context.Binding.GetReadChannelSource(new [] { context.ChannelSource.ServerDescription }, cancellationToken)); context.ReplaceChannel(context.ChannelSource.GetChannel(cancellationToken)); } catch @@ -96,7 +96,7 @@ public static async Task ExecuteAsync(IRetryableReadOperation< try { - context.ReplaceChannelSource(context.Binding.GetReadChannelSource(new []{ context.ChannelSource.ServerDescription }, cancellationToken)); + context.ReplaceChannelSource(context.Binding.GetReadChannelSource(new [] { context.ChannelSource.ServerDescription }, cancellationToken)); context.ReplaceChannel(context.ChannelSource.GetChannel(cancellationToken)); } catch diff --git a/src/MongoDB.Driver.Core/Core/Operations/RetryableWriteOperationExecutor.cs b/src/MongoDB.Driver.Core/Core/Operations/RetryableWriteOperationExecutor.cs index edb59aec00a..d6be77757d6 100644 --- a/src/MongoDB.Driver.Core/Core/Operations/RetryableWriteOperationExecutor.cs +++ b/src/MongoDB.Driver.Core/Core/Operations/RetryableWriteOperationExecutor.cs @@ -53,7 +53,7 @@ public static TResult Execute(IRetryableWriteOperation operati try { - context.ReplaceChannelSource(context.Binding.GetWriteChannelSource(new []{ context.ChannelSource.ServerDescription }, cancellationToken)); + context.ReplaceChannelSource(context.Binding.GetWriteChannelSource(new [] { context.ChannelSource.ServerDescription }, cancellationToken)); context.ReplaceChannel(context.ChannelSource.GetChannel(cancellationToken)); } catch @@ -104,7 +104,7 @@ public static async Task ExecuteAsync(IRetryableWriteOperation try { - context.ReplaceChannelSource(await context.Binding.GetWriteChannelSourceAsync(new []{ context.ChannelSource.ServerDescription }, cancellationToken).ConfigureAwait(false)); + context.ReplaceChannelSource(await context.Binding.GetWriteChannelSourceAsync(new [] { context.ChannelSource.ServerDescription }, cancellationToken).ConfigureAwait(false)); context.ReplaceChannel(await context.ChannelSource.GetChannelAsync(cancellationToken).ConfigureAwait(false)); } catch diff --git a/tests/MongoDB.Driver.Core.Tests/Core/Bindings/WritableServerBindingTests.cs b/tests/MongoDB.Driver.Core.Tests/Core/Bindings/WritableServerBindingTests.cs index 90ac2dd0cbe..62cf9a20b70 100644 --- a/tests/MongoDB.Driver.Core.Tests/Core/Bindings/WritableServerBindingTests.cs +++ b/tests/MongoDB.Driver.Core.Tests/Core/Bindings/WritableServerBindingTests.cs @@ -202,7 +202,7 @@ public void GetWriteChannelSourceAsync_should_use_a_writable_server_selector_to_ [Theory] [ParameterAttributeData] - public void GetWriteChannelSource_should_use_a_composite_server_selector_to_select_the_server_from_the_cluster_when_deprioritized_servers_present( + public async void GetWriteChannelSource_should_use_a_composite_server_selector_to_select_the_server_from_the_cluster_when_deprioritized_servers_present( [Values(false, true)] bool async) { @@ -227,7 +227,7 @@ public void GetWriteChannelSource_should_use_a_composite_server_selector_to_sele { _mockCluster.Setup(c => c.SelectServerAsync(It.Is(cp => cp.ToString().Contains("PriorityServerSelector")), CancellationToken.None)).Returns(Task.FromResult(selectedServer)); - subject.GetWriteChannelSourceAsync(deprioritizedServers, CancellationToken.None).GetAwaiter().GetResult(); + await subject.GetWriteChannelSourceAsync(deprioritizedServers, CancellationToken.None); _mockCluster.Verify(c => c.SelectServerAsync(It.Is(cp => cp.ToString().Contains("PriorityServerSelector")), CancellationToken.None), Times.Once); } diff --git a/tests/MongoDB.Driver.Core.Tests/Core/Clusters/ClusterTests.cs b/tests/MongoDB.Driver.Core.Tests/Core/Clusters/ClusterTests.cs index 9cea5cb3370..fb9d1b3ecc9 100644 --- a/tests/MongoDB.Driver.Core.Tests/Core/Clusters/ClusterTests.cs +++ b/tests/MongoDB.Driver.Core.Tests/Core/Clusters/ClusterTests.cs @@ -415,7 +415,7 @@ public void SelectServer_should_keep_trying_to_match_by_waiting_on_cluster_descr [Theory] [ParameterAttributeData] - public void SelectServer_should_ignore_deprioritized_servers_if_cluster_is_sharded( + public async void SelectServer_should_ignore_deprioritized_servers_if_cluster_is_sharded( [Values(false, true)] bool async) { @@ -442,7 +442,7 @@ public void SelectServer_should_ignore_deprioritized_servers_if_cluster_is_shard IServer result; if (async) { - result = subject.SelectServerAsync(selector, CancellationToken.None).GetAwaiter().GetResult(); + result = await subject.SelectServerAsync(selector, CancellationToken.None); } else { @@ -461,12 +461,12 @@ public void SelectServer_should_ignore_deprioritized_servers_if_cluster_is_shard [Theory] [ParameterAttributeData] - public void SelectServer_should_return_deprioritized_servers_if_no_other_servers_exist_or_cluster_not_sharded( + public async void SelectServer_should_return_deprioritized_servers_if_no_other_servers_exist_or_cluster_not_sharded( [Values(false, true)] bool async, - [Values(false, true)] bool IsSharded) + [Values(false, true)] bool isSharded) { #pragma warning disable CS0618 // Type or member is obsolete - StubCluster subject = IsSharded ? CreateSubject(ClusterConnectionMode.Sharded) : CreateSubject(); + StubCluster subject = isSharded ? CreateSubject(ClusterConnectionMode.Sharded) : CreateSubject(); #pragma warning restore CS0618 // Type or member is obsolete subject.Initialize(); @@ -480,27 +480,24 @@ public void SelectServer_should_return_deprioritized_servers_if_no_other_servers var selector = new PriorityServerSelector(deprioritizedServers); - for (int i = 0; i < 15; i++) + _capturedEvents.Clear(); + IServer result; + if (async) { - _capturedEvents.Clear(); - IServer result; - if (async) - { - result = subject.SelectServerAsync(selector, CancellationToken.None).GetAwaiter().GetResult(); - } - else - { - result = subject.SelectServer(selector, CancellationToken.None); - } + result = await subject.SelectServerAsync(selector, CancellationToken.None); + } + else + { + result = subject.SelectServer(selector, CancellationToken.None); + } - result.Should().NotBeNull(); + result.Should().NotBeNull(); - deprioritizedServers.Should().Contain(d => d.EndPoint == result.Description.EndPoint); + deprioritizedServers.Should().Contain(d => d.EndPoint == result.Description.EndPoint); - _capturedEvents.Next().Should().BeOfType(); - _capturedEvents.Next().Should().BeOfType(); - _capturedEvents.Any().Should().BeFalse(); - } + _capturedEvents.Next().Should().BeOfType(); + _capturedEvents.Next().Should().BeOfType(); + _capturedEvents.Any().Should().BeFalse(); } [Fact] diff --git a/tests/MongoDB.Driver.Tests/Specifications/retryable-reads/RetryableReadsProseTests.cs b/tests/MongoDB.Driver.Tests/Specifications/retryable-reads/RetryableReadsProseTests.cs index 4d9002d459c..db8330df4ed 100644 --- a/tests/MongoDB.Driver.Tests/Specifications/retryable-reads/RetryableReadsProseTests.cs +++ b/tests/MongoDB.Driver.Tests/Specifications/retryable-reads/RetryableReadsProseTests.cs @@ -29,7 +29,6 @@ using MongoDB.Driver.Core.TestHelpers; using MongoDB.Driver.Core.TestHelpers.XunitExtensions; using MongoDB.Driver.TestHelpers; -using MongoDB.Driver.Tests.Specifications.connection_monitoring_and_pooling; using MongoDB.TestHelpers.XunitExtensions; using Xunit; @@ -149,7 +148,7 @@ public void Sharded_cluster_retryable_reads_are_retried_on_different_mongos_if_a s.RetryReads = true; s.ClusterConfigurator = b => b.Subscribe(eventCapturer); } - , null, true); + , null, useMultipleShardRouters: true); var failPointServer1 = client.Cluster.SelectServer(new EndPointServerSelector(client.Cluster.Description.Servers[0].EndPoint), default); var failPointServer2 = client.Cluster.SelectServer(new EndPointServerSelector(client.Cluster.Description.Servers[1].EndPoint), default); @@ -169,11 +168,11 @@ public void Sharded_cluster_retryable_reads_are_retried_on_different_mongos_if_a failedEvents.Length.Should().Be(2); failedEvents[0].CommandName.Should().Be(failedEvents[1].CommandName).And.Be("find"); - failedEvents[0].ConnectionId.ServerId().Should().NotBe(failedEvents[1].ConnectionId.ServerId()); + failedEvents[0].ConnectionId.ServerId.Should().NotBe(failedEvents[1].ConnectionId.ServerId); } [Fact] - public void Sharded_cluster_retryable_reads_are_retried_on_same_mongo_if_no_other_is_available() + public void Sharded_cluster_retryable_reads_are_retried_on_same_mongos_if_no_other_is_available() { RequireServer.Check() .Supports(Feature.FailPointsFailCommandForSharded) @@ -199,7 +198,7 @@ public void Sharded_cluster_retryable_reads_are_retried_on_same_mongo_if_no_othe s.DirectConnection = false; s.ClusterConfigurator = b => b.Subscribe(eventCapturer); } - , null); + , null, useMultipleShardRouters: false); var failPointServer = client.Cluster.SelectServer(new EndPointServerSelector(client.Cluster.Description.Servers[0].EndPoint), default); @@ -217,7 +216,7 @@ public void Sharded_cluster_retryable_reads_are_retried_on_same_mongo_if_no_othe succeededEvents.Length.Should().Be(1); failedEvents[0].CommandName.Should().Be(succeededEvents[0].CommandName).And.Be("find"); - failedEvents[0].ConnectionId.ServerId().Should().Be(succeededEvents[0].ConnectionId.ServerId()); + failedEvents[0].ConnectionId.ServerId.Should().Be(succeededEvents[0].ConnectionId.ServerId); } // private methods diff --git a/tests/MongoDB.Driver.Tests/Specifications/retryable-writes/prose-tests/RetryWriteOnOtherMongos.cs b/tests/MongoDB.Driver.Tests/Specifications/retryable-writes/prose-tests/RetryWriteOnOtherMongos.cs index ccf1b8207cc..7240eb86c08 100644 --- a/tests/MongoDB.Driver.Tests/Specifications/retryable-writes/prose-tests/RetryWriteOnOtherMongos.cs +++ b/tests/MongoDB.Driver.Tests/Specifications/retryable-writes/prose-tests/RetryWriteOnOtherMongos.cs @@ -1,4 +1,4 @@ -/* Copyright 2021-present MongoDB Inc. +/* Copyright 2010-present MongoDB Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -24,7 +24,6 @@ using MongoDB.Driver.Core.Misc; using MongoDB.Driver.Core.TestHelpers; using MongoDB.Driver.Core.TestHelpers.XunitExtensions; -using MongoDB.Driver.Tests.Specifications.connection_monitoring_and_pooling; using Xunit; namespace MongoDB.Driver.Tests.Specifications.retryable_writes.prose_tests @@ -59,7 +58,7 @@ public void Sharded_cluster_retryable_writes_are_retried_on_different_mongos_if_ s.RetryWrites = true; s.ClusterConfigurator = b => b.Subscribe(eventCapturer); } - , null, true); + , null, useMultipleShardRouters: true); var failPointServer1 = client.Cluster.SelectServer(new EndPointServerSelector(client.Cluster.Description.Servers[0].EndPoint), default); var failPointServer2 = client.Cluster.SelectServer(new EndPointServerSelector(client.Cluster.Description.Servers[1].EndPoint), default); @@ -79,7 +78,7 @@ public void Sharded_cluster_retryable_writes_are_retried_on_different_mongos_if_ failedEvents.Length.Should().Be(2); failedEvents[0].CommandName.Should().Be(failedEvents[1].CommandName).And.Be("insert"); - failedEvents[0].ConnectionId.ServerId().Should().NotBe(failedEvents[1].ConnectionId.ServerId()); + failedEvents[0].ConnectionId.ServerId.Should().NotBe(failedEvents[1].ConnectionId.ServerId); } [Fact] @@ -110,7 +109,7 @@ public void Sharded_cluster_retryable_writes_are_retried_on_same_mongo_if_no_oth s.DirectConnection = false; s.ClusterConfigurator = b => b.Subscribe(eventCapturer); } - , null); + , null, useMultipleShardRouters: false); var failPointServer = client.Cluster.SelectServer(new EndPointServerSelector(client.Cluster.Description.Servers[0].EndPoint), default); @@ -128,7 +127,7 @@ public void Sharded_cluster_retryable_writes_are_retried_on_same_mongo_if_no_oth succeededEvents.Length.Should().Be(1); failedEvents[0].CommandName.Should().Be(succeededEvents[0].CommandName).And.Be("insert"); - failedEvents[0].ConnectionId.ServerId().Should().Be(succeededEvents[0].ConnectionId.ServerId()); + failedEvents[0].ConnectionId.ServerId.Should().Be(succeededEvents[0].ConnectionId.ServerId); } } } From 42e8ba299eaab2d038f184f42e00a4866d8bffd5 Mon Sep 17 00:00:00 2001 From: adelinowona Date: Tue, 28 May 2024 14:09:44 -0400 Subject: [PATCH 18/24] Avoid using async void --- .../Core/Bindings/WritableServerBindingTests.cs | 2 +- tests/MongoDB.Driver.Core.Tests/Core/Clusters/ClusterTests.cs | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/tests/MongoDB.Driver.Core.Tests/Core/Bindings/WritableServerBindingTests.cs b/tests/MongoDB.Driver.Core.Tests/Core/Bindings/WritableServerBindingTests.cs index 62cf9a20b70..fa8795ae666 100644 --- a/tests/MongoDB.Driver.Core.Tests/Core/Bindings/WritableServerBindingTests.cs +++ b/tests/MongoDB.Driver.Core.Tests/Core/Bindings/WritableServerBindingTests.cs @@ -202,7 +202,7 @@ public void GetWriteChannelSourceAsync_should_use_a_writable_server_selector_to_ [Theory] [ParameterAttributeData] - public async void GetWriteChannelSource_should_use_a_composite_server_selector_to_select_the_server_from_the_cluster_when_deprioritized_servers_present( + public async Task GetWriteChannelSource_should_use_a_composite_server_selector_to_select_the_server_from_the_cluster_when_deprioritized_servers_present( [Values(false, true)] bool async) { diff --git a/tests/MongoDB.Driver.Core.Tests/Core/Clusters/ClusterTests.cs b/tests/MongoDB.Driver.Core.Tests/Core/Clusters/ClusterTests.cs index fb9d1b3ecc9..d367ab5c0aa 100644 --- a/tests/MongoDB.Driver.Core.Tests/Core/Clusters/ClusterTests.cs +++ b/tests/MongoDB.Driver.Core.Tests/Core/Clusters/ClusterTests.cs @@ -415,7 +415,7 @@ public void SelectServer_should_keep_trying_to_match_by_waiting_on_cluster_descr [Theory] [ParameterAttributeData] - public async void SelectServer_should_ignore_deprioritized_servers_if_cluster_is_sharded( + public async Task SelectServer_should_ignore_deprioritized_servers_if_cluster_is_sharded( [Values(false, true)] bool async) { @@ -461,7 +461,7 @@ public async void SelectServer_should_ignore_deprioritized_servers_if_cluster_is [Theory] [ParameterAttributeData] - public async void SelectServer_should_return_deprioritized_servers_if_no_other_servers_exist_or_cluster_not_sharded( + public async Task SelectServer_should_return_deprioritized_servers_if_no_other_servers_exist_or_cluster_not_sharded( [Values(false, true)] bool async, [Values(false, true)] bool isSharded) { From 9a7182aeeb68f2612d2fcab57348f0e56b430f17 Mon Sep 17 00:00:00 2001 From: adelinowona Date: Tue, 28 May 2024 15:14:53 -0400 Subject: [PATCH 19/24] Avoid double awaiting --- .../Core/Bindings/ReadPreferenceBinding.cs | 4 ++-- .../Core/Bindings/WritableServerBinding.cs | 12 ++++++------ 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/src/MongoDB.Driver.Core/Core/Bindings/ReadPreferenceBinding.cs b/src/MongoDB.Driver.Core/Core/Bindings/ReadPreferenceBinding.cs index 4bd662f53a7..a84fa4fe932 100644 --- a/src/MongoDB.Driver.Core/Core/Bindings/ReadPreferenceBinding.cs +++ b/src/MongoDB.Driver.Core/Core/Bindings/ReadPreferenceBinding.cs @@ -72,9 +72,9 @@ public IChannelSourceHandle GetReadChannelSource(CancellationToken cancellationT } /// - public async Task GetReadChannelSourceAsync(CancellationToken cancellationToken) + public Task GetReadChannelSourceAsync(CancellationToken cancellationToken) { - return await GetReadChannelSourceAsync(null, cancellationToken).ConfigureAwait(false); + return GetReadChannelSourceAsync(null, cancellationToken); } /// diff --git a/src/MongoDB.Driver.Core/Core/Bindings/WritableServerBinding.cs b/src/MongoDB.Driver.Core/Core/Bindings/WritableServerBinding.cs index 2cf1afb470b..44f323d1360 100644 --- a/src/MongoDB.Driver.Core/Core/Bindings/WritableServerBinding.cs +++ b/src/MongoDB.Driver.Core/Core/Bindings/WritableServerBinding.cs @@ -67,9 +67,9 @@ public IChannelSourceHandle GetReadChannelSource(CancellationToken cancellationT } /// - public async Task GetReadChannelSourceAsync(CancellationToken cancellationToken) + public Task GetReadChannelSourceAsync(CancellationToken cancellationToken) { - return await GetReadChannelSourceAsync(null, cancellationToken).ConfigureAwait(false); + return GetReadChannelSourceAsync(null, cancellationToken); } /// @@ -127,9 +127,9 @@ public IChannelSourceHandle GetWriteChannelSource(IReadOnlyCollection - public async Task GetWriteChannelSourceAsync(CancellationToken cancellationToken) + public Task GetWriteChannelSourceAsync(CancellationToken cancellationToken) { - return await GetWriteChannelSourceAsync(deprioritizedServers: null, cancellationToken).ConfigureAwait(false); + return GetWriteChannelSourceAsync(deprioritizedServers: null, cancellationToken); } /// @@ -141,9 +141,9 @@ public async Task GetWriteChannelSourceAsync(IReadOnlyColl } /// - public async Task GetWriteChannelSourceAsync(IMayUseSecondaryCriteria mayUseSecondary, CancellationToken cancellationToken) + public Task GetWriteChannelSourceAsync(IMayUseSecondaryCriteria mayUseSecondary, CancellationToken cancellationToken) { - return await GetWriteChannelSourceAsync(null, mayUseSecondary, cancellationToken).ConfigureAwait(false); + return GetWriteChannelSourceAsync(null, mayUseSecondary, cancellationToken); } /// From b50bc5209eaae829accbbcde067735b009413b1a Mon Sep 17 00:00:00 2001 From: adelinowona Date: Tue, 28 May 2024 15:27:32 -0400 Subject: [PATCH 20/24] Fix spacing --- .../Core/Operations/RetryableReadOperationExecutor.cs | 4 ++-- .../Core/Operations/RetryableWriteOperationExecutor.cs | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/MongoDB.Driver.Core/Core/Operations/RetryableReadOperationExecutor.cs b/src/MongoDB.Driver.Core/Core/Operations/RetryableReadOperationExecutor.cs index 1c81b572b7c..cdb74827dc0 100644 --- a/src/MongoDB.Driver.Core/Core/Operations/RetryableReadOperationExecutor.cs +++ b/src/MongoDB.Driver.Core/Core/Operations/RetryableReadOperationExecutor.cs @@ -51,7 +51,7 @@ public static TResult Execute(IRetryableReadOperation operatio try { - context.ReplaceChannelSource(context.Binding.GetReadChannelSource(new [] { context.ChannelSource.ServerDescription }, cancellationToken)); + context.ReplaceChannelSource(context.Binding.GetReadChannelSource(new[] { context.ChannelSource.ServerDescription }, cancellationToken)); context.ReplaceChannel(context.ChannelSource.GetChannel(cancellationToken)); } catch @@ -96,7 +96,7 @@ public static async Task ExecuteAsync(IRetryableReadOperation< try { - context.ReplaceChannelSource(context.Binding.GetReadChannelSource(new [] { context.ChannelSource.ServerDescription }, cancellationToken)); + context.ReplaceChannelSource(context.Binding.GetReadChannelSource(new[] { context.ChannelSource.ServerDescription }, cancellationToken)); context.ReplaceChannel(context.ChannelSource.GetChannel(cancellationToken)); } catch diff --git a/src/MongoDB.Driver.Core/Core/Operations/RetryableWriteOperationExecutor.cs b/src/MongoDB.Driver.Core/Core/Operations/RetryableWriteOperationExecutor.cs index d6be77757d6..6e73af1e758 100644 --- a/src/MongoDB.Driver.Core/Core/Operations/RetryableWriteOperationExecutor.cs +++ b/src/MongoDB.Driver.Core/Core/Operations/RetryableWriteOperationExecutor.cs @@ -53,7 +53,7 @@ public static TResult Execute(IRetryableWriteOperation operati try { - context.ReplaceChannelSource(context.Binding.GetWriteChannelSource(new [] { context.ChannelSource.ServerDescription }, cancellationToken)); + context.ReplaceChannelSource(context.Binding.GetWriteChannelSource(new[] { context.ChannelSource.ServerDescription }, cancellationToken)); context.ReplaceChannel(context.ChannelSource.GetChannel(cancellationToken)); } catch @@ -104,7 +104,7 @@ public static async Task ExecuteAsync(IRetryableWriteOperation try { - context.ReplaceChannelSource(await context.Binding.GetWriteChannelSourceAsync(new [] { context.ChannelSource.ServerDescription }, cancellationToken).ConfigureAwait(false)); + context.ReplaceChannelSource(await context.Binding.GetWriteChannelSourceAsync(new[] { context.ChannelSource.ServerDescription }, cancellationToken).ConfigureAwait(false)); context.ReplaceChannel(await context.ChannelSource.GetChannelAsync(cancellationToken).ConfigureAwait(false)); } catch From 507cda16757a74ed09bb36e12687eb4bff83acf7 Mon Sep 17 00:00:00 2001 From: adelinowona Date: Tue, 28 May 2024 15:52:40 -0400 Subject: [PATCH 21/24] ensure deprioritized servers collection is not empty as well --- .../Core/Clusters/ServerSelectors/PriorityServerSelector.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/MongoDB.Driver.Core/Core/Clusters/ServerSelectors/PriorityServerSelector.cs b/src/MongoDB.Driver.Core/Core/Clusters/ServerSelectors/PriorityServerSelector.cs index 4d99594d36f..290b8ae30ca 100644 --- a/src/MongoDB.Driver.Core/Core/Clusters/ServerSelectors/PriorityServerSelector.cs +++ b/src/MongoDB.Driver.Core/Core/Clusters/ServerSelectors/PriorityServerSelector.cs @@ -33,7 +33,7 @@ public sealed class PriorityServerSelector : IServerSelector /// The collection of servers to deprioritize. public PriorityServerSelector(IReadOnlyCollection deprioritizedServers) { - _deprioritizedServers = Ensure.IsNotNull(deprioritizedServers, nameof(deprioritizedServers)); + _deprioritizedServers = Ensure.IsNotNullOrEmpty(deprioritizedServers, nameof(deprioritizedServers)) as IReadOnlyCollection; } /// From b519cd46210a6ed17f6cefd1aed17008758e748a Mon Sep 17 00:00:00 2001 From: adelinowona Date: Tue, 28 May 2024 16:04:25 -0400 Subject: [PATCH 22/24] Add PriorityServerSelector tests --- .../PriorityServerSelectorTests.cs | 83 +++++++++++++++++++ 1 file changed, 83 insertions(+) create mode 100644 tests/MongoDB.Driver.Core.Tests/Core/Clusters/ServerSelectors/PriorityServerSelectorTests.cs diff --git a/tests/MongoDB.Driver.Core.Tests/Core/Clusters/ServerSelectors/PriorityServerSelectorTests.cs b/tests/MongoDB.Driver.Core.Tests/Core/Clusters/ServerSelectors/PriorityServerSelectorTests.cs new file mode 100644 index 00000000000..16aa265ad29 --- /dev/null +++ b/tests/MongoDB.Driver.Core.Tests/Core/Clusters/ServerSelectors/PriorityServerSelectorTests.cs @@ -0,0 +1,83 @@ +/* Copyright 2010-present MongoDB Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +using System.Linq; +using System.Net; +using FluentAssertions; +using MongoDB.Driver.Core.Helpers; +using MongoDB.Driver.Core.Servers; +using Xunit; + +namespace MongoDB.Driver.Core.Clusters.ServerSelectors; + +public class PriorityServerSelectorTests +{ + private readonly ClusterDescription _description; + private readonly ServerDescription _server1; + private readonly ServerDescription _server2; + private readonly ServerDescription _server3; + + public PriorityServerSelectorTests() + { + var clusterId = new ClusterId(); + + _server1 = ServerDescriptionHelper.Connected(clusterId, new DnsEndPoint("localhost", 27017)); + _server2 = ServerDescriptionHelper.Connected(clusterId, new DnsEndPoint("localhost", 27018)); + _server3 = ServerDescriptionHelper.Connected(clusterId, new DnsEndPoint("localhost", 27019)); + +#pragma warning disable CS0618 // Type or member is obsolete + _description = new ClusterDescription( + clusterId, + ClusterConnectionMode.Sharded, + ClusterType.Sharded, + new[] { _server1, _server2, _server3 }); +#pragma warning restore CS0618 // Type or member is obsolete + } + + [Fact] + public void Should_select_all_the_servers_not_deprioritized() + { + var subject = new PriorityServerSelector(new[] { _server1, _server2 }); + + var result = subject.SelectServers(_description, _description.Servers).ToList(); + + result.Count.Should().Be(1); + result.Should().BeEquivalentTo(_server3); + } + + [Fact] + public void Should_select_all_the_servers_if_all_servers_are_deprioritized() + { + var subject = new PriorityServerSelector(new[] { _server1, _server2, _server3}); + + var result = subject.SelectServers(_description, _description.Servers).ToList(); + + result.Count.Should().Be(3); + result.Should().BeEquivalentTo(_description.Servers); + } + + [Fact] + public void Should_ignore_deprioritized_servers_if_not_in_sharded_mode() + { + var changedDescription = _description.WithType(ClusterType.Unknown); + + var subject = new PriorityServerSelector(new[] { _server2, _server3 }); + + var result = subject.SelectServers(changedDescription, _description.Servers).ToList(); + + result.Count.Should().Be(3); + result.Should().BeEquivalentTo(_description.Servers); + } +} From f723d9383f66f04081aa782b242ffe91024a4ad3 Mon Sep 17 00:00:00 2001 From: adelinowona Date: Wed, 5 Jun 2024 19:38:35 -0400 Subject: [PATCH 23/24] Fix failing evergreen tests --- .../Core/Bindings/WritableServerBindingTests.cs | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/tests/MongoDB.Driver.Core.Tests/Core/Bindings/WritableServerBindingTests.cs b/tests/MongoDB.Driver.Core.Tests/Core/Bindings/WritableServerBindingTests.cs index fa8795ae666..55a9d3eca62 100644 --- a/tests/MongoDB.Driver.Core.Tests/Core/Bindings/WritableServerBindingTests.cs +++ b/tests/MongoDB.Driver.Core.Tests/Core/Bindings/WritableServerBindingTests.cs @@ -211,17 +211,18 @@ public async Task GetWriteChannelSource_should_use_a_composite_server_selector_t var clusterId = new ClusterId(); var endPoint = new DnsEndPoint("localhost", 27017); + var server = new ServerDescription(new ServerId(clusterId, endPoint), endPoint); #pragma warning disable CS0618 // Type or member is obsolete var initialClusterDescription = new ClusterDescription( clusterId, ClusterConnectionMode.Sharded, ClusterType.Unknown, - new[] { new ServerDescription(new ServerId(clusterId, endPoint), endPoint) }); + new[] { server }); #pragma warning restore CS0618 // Type or member is obsolete var finalClusterDescription = initialClusterDescription.WithType(ClusterType.Sharded); _mockCluster.SetupSequence(c => c.Description).Returns(initialClusterDescription).Returns(finalClusterDescription); - var deprioritizedServers = new ServerDescription[] { }; + var deprioritizedServers = new ServerDescription[] { server }; if (async) { From 27d3bce71649bc7293118d34c57d92e85351ecff Mon Sep 17 00:00:00 2001 From: adelinowona Date: Mon, 10 Jun 2024 13:54:34 -0400 Subject: [PATCH 24/24] address review comments --- .../Core/Clusters/ServerSelectors/PriorityServerSelector.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/MongoDB.Driver.Core/Core/Clusters/ServerSelectors/PriorityServerSelector.cs b/src/MongoDB.Driver.Core/Core/Clusters/ServerSelectors/PriorityServerSelector.cs index 290b8ae30ca..6d125a879a7 100644 --- a/src/MongoDB.Driver.Core/Core/Clusters/ServerSelectors/PriorityServerSelector.cs +++ b/src/MongoDB.Driver.Core/Core/Clusters/ServerSelectors/PriorityServerSelector.cs @@ -51,6 +51,6 @@ public IEnumerable SelectServers(ClusterDescription cluster, } /// - public override string ToString() => "PriorityServerSelector"; + public override string ToString() => $"PriorityServerSelector{{{{ Deprioritized servers: {string.Join(", ", _deprioritizedServers.Select(s => s.EndPoint))} }}}}"; } }