public IServer SelectServer() { lock (_cluster._descriptionLock) { _descriptionChangedTask = _cluster._descriptionChangedTaskCompletionSource.Task; _description = _cluster._description; } if (!_serverSelectionWaitQueueEntered) { var selectingServerEventHandler = _cluster._selectingServerEventHandler; if (selectingServerEventHandler != null) { // this is our first time through... selectingServerEventHandler(new ClusterSelectingServerEvent( _description, _selector, EventContext.OperationId)); } } MongoIncompatibleDriverException.ThrowIfNotSupported(_description); var connectedServers = _description.Servers.Where(s => s.State == ServerState.Connected); var selectedServers = _selector.SelectServers(_description, connectedServers).ToList(); while (selectedServers.Count > 0) { var server = selectedServers.Count == 1 ? selectedServers[0] : __randomServerSelector.SelectServers(_description, selectedServers).Single(); IClusterableServer selectedServer; if (_cluster.TryGetServer(server.EndPoint, out selectedServer)) { _stopwatch.Stop(); var selectedServerEventHandler = _cluster._selectedServerEventHandler; if (selectedServerEventHandler != null) { selectedServerEventHandler(new ClusterSelectedServerEvent( _description, _selector, server, _stopwatch.Elapsed, EventContext.OperationId)); } return(selectedServer); } selectedServers.Remove(server); } return(null); }
private void RunNonErrorTest(BsonDocument definition, ClusterDescription clusterDescription, IServerSelector selector, TimeSpan heartbeatInterval) { var suitableServers = BuildServerDescriptions((BsonArray)definition["suitable_servers"], heartbeatInterval).ToList(); var selectedServers = selector.SelectServers(clusterDescription, clusterDescription.Servers).ToList(); AssertServers(suitableServers, selectedServers); selector = new CompositeServerSelector(new[] { selector, new LatencyLimitingServerSelector(TimeSpan.FromMilliseconds(15)) }); var inLatencyWindowServers = BuildServerDescriptions((BsonArray)definition["in_latency_window"], heartbeatInterval).ToList(); selectedServers = selector.SelectServers(clusterDescription, clusterDescription.Servers).ToList(); AssertServers(inLatencyWindowServers, selectedServers); }
public async Task <IServer> SelectServerAsync(IServerSelector selector, TimeSpan timeout, CancellationToken cancellationToken) { ThrowIfDisposedOrNotOpen(); Ensure.IsNotNull(selector, "selector"); var slidingTimeout = new SlidingTimeout(timeout); while (true) { cancellationToken.ThrowIfCancellationRequested(); Task descriptionChangedTask; ClusterDescription description; lock (_descriptionLock) { descriptionChangedTask = _descriptionChangedTaskCompletionSource.Task; description = _description; } ThrowIfIncompatible(description); var connectedServers = description.Servers.Where(s => s.State == ServerState.Connected); var selectedServers = selector.SelectServers(description, connectedServers).ToList(); while (selectedServers.Count > 0) { var server = selectedServers.Count == 1 ? selectedServers[0] : __randomServerSelector.SelectServers(description, selectedServers).Single(); IClusterableServer selectedServer; if (TryGetServer(server.EndPoint, out selectedServer)) { return(selectedServer); } selectedServers.Remove(server); } Invalidate(); await descriptionChangedTask.WithTimeout(slidingTimeout, cancellationToken); } }
private IDisposable RequestStart(IServerSelector serverSelector, ReadPreference readPreference) { var request = __threadStaticRequest; if (request != null) { var selected = serverSelector.SelectServers(_cluster.Description, new[] { request.ServerDescription }).ToList(); if (selected.Count == 0) { throw new InvalidOperationException("A nested call to RequestStart was made that is not compatible with the existing request."); } request.NestingLevel++; return(new RequestStartResult(this)); } IReadBindingHandle channelBinding; ConnectionId connectionId; var server = _cluster.SelectServer(serverSelector, CancellationToken.None); using (var channel = server.GetChannel(CancellationToken.None)) { if (readPreference.ReadPreferenceMode == ReadPreferenceMode.Primary) { channelBinding = new ReadWriteBindingHandle(new ChannelReadWriteBinding(server, channel.Fork(), NoCoreSession.NewHandle())); } else { channelBinding = new ReadBindingHandle(new ChannelReadBinding(server, channel.Fork(), readPreference, NoCoreSession.NewHandle())); } connectionId = channel.ConnectionDescription.ConnectionId; } var serverDescription = server.Description; var serverInstance = _serverInstances.Single(i => EndPointHelper.Equals(i.EndPoint, serverDescription.EndPoint)); var session = _operationExecutor.StartImplicitSession(CancellationToken.None); __threadStaticRequest = new Request(serverDescription, serverInstance, channelBinding, connectionId, session); return(new RequestStartResult(this)); }
private IDisposable RequestStart(IServerSelector serverSelector, ReadPreference readPreference) { var request = __threadStaticRequest; if (request != null) { var selected = serverSelector.SelectServers(_cluster.Description, new[] { request.ServerDescription }).ToList(); if (selected.Count == 0) { throw new InvalidOperationException("A nested call to RequestStart was made that is not compatible with the existing request."); } request.NestingLevel++; return(new RequestStartResult(this)); } IReadBindingHandle connectionBinding; var server = _cluster.SelectServer(serverSelector); using (var connection = server.GetConnection()) { if (readPreference.ReadPreferenceMode == ReadPreferenceMode.Primary) { connectionBinding = new ReadWriteBindingHandle(new ConnectionReadWriteBinding(server, connection.Fork())); } else { connectionBinding = new ReadBindingHandle(new ConnectionReadBinding(server, connection.Fork(), readPreference)); } } var serverDescription = server.Description; var endPoint = (DnsEndPoint)serverDescription.EndPoint; var serverAddress = new MongoServerAddress(endPoint.Host, endPoint.Port); var serverInstance = _serverInstances.Single(i => i.Address == serverAddress); __threadStaticRequest = new Request(serverDescription, serverInstance, connectionBinding); return(new RequestStartResult(this)); }
public async Task <IServer> SelectServerAsync(IServerSelector selector, CancellationToken cancellationToken) { ThrowIfDisposedOrNotOpen(); Ensure.IsNotNull(selector, "selector"); var timeoutAt = DateTime.UtcNow + _settings.ServerSelectionTimeout; var serverSelectionWaitQueueEntered = false; try { while (true) { cancellationToken.ThrowIfCancellationRequested(); Task descriptionChangedTask; ClusterDescription description; lock (_descriptionLock) { descriptionChangedTask = _descriptionChangedTaskCompletionSource.Task; description = _description; } ThrowIfIncompatible(description); var connectedServers = description.Servers.Where(s => s.State == ServerState.Connected); var selectedServers = selector.SelectServers(description, connectedServers).ToList(); while (selectedServers.Count > 0) { var server = selectedServers.Count == 1 ? selectedServers[0] : __randomServerSelector.SelectServers(description, selectedServers).Single(); IClusterableServer selectedServer; if (TryGetServer(server.EndPoint, out selectedServer)) { return(selectedServer); } selectedServers.Remove(server); } if (!serverSelectionWaitQueueEntered) { EnterServerSelectionWaitQueue(); serverSelectionWaitQueueEntered = true; } var timeoutRemaining = timeoutAt - DateTime.UtcNow; if (timeoutRemaining <= TimeSpan.Zero) { ThrowTimeoutException(description); } await WaitForDescriptionChangedAsync(description, descriptionChangedTask, timeoutRemaining, cancellationToken).ConfigureAwait(false); } } finally { if (serverSelectionWaitQueueEntered) { ExitServerSelectionWaitQueue(); } } }
public IServer SelectServer() { lock (_cluster._descriptionLock) { _descriptionChangedTask = _cluster._descriptionChangedTaskCompletionSource.Task; _description = _cluster._description; } if (!_serverSelectionWaitQueueEntered) { var selectingServerEventHandler = _cluster._selectingServerEventHandler; if (selectingServerEventHandler != null) { // this is our first time through... selectingServerEventHandler(new ClusterSelectingServerEvent( _description, _selector, EventContext.OperationId)); } } MongoIncompatibleDriverException.ThrowIfNotSupported(_description); _connectedServers.Clear(); _connectedServerDescriptions.Clear(); foreach (var description in _description.Servers) { if (description.State == ServerState.Connected && _cluster.TryGetServer(description.EndPoint, out var server)) { _connectedServers.Add(server); _connectedServerDescriptions.Add(description); } } var selectedServersDescriptions = _selector .SelectServers(_description, _connectedServerDescriptions) .ToList(); IServer selectedServer = null; if (selectedServersDescriptions.Count > 0) { var selectedServerDescription = selectedServersDescriptions.Count == 1 ? selectedServersDescriptions[0] : __randomServerSelector.SelectServers(_description, selectedServersDescriptions).Single(); selectedServer = _connectedServers.FirstOrDefault(s => EndPointHelper.Equals(s.EndPoint, selectedServerDescription.EndPoint)); } if (selectedServer != null) { _stopwatch.Stop(); _cluster._selectedServerEventHandler?.Invoke(new ClusterSelectedServerEvent( _description, _selector, selectedServer.Description, _stopwatch.Elapsed, EventContext.OperationId)); } return(selectedServer); }
private void RunErrorTest(ClusterDescription clusterDescription, IServerSelector selector) { var exception = Record.Exception(() => selector.SelectServers(clusterDescription, clusterDescription.Servers).ToList()); exception.Should().NotBeNull(); }
public async Task<IServer> SelectServerAsync(IServerSelector selector, TimeSpan timeout, CancellationToken cancellationToken) { ThrowIfDisposedOrNotOpen(); Ensure.IsNotNull(selector, "selector"); var slidingTimeout = new SlidingTimeout(timeout); while (true) { cancellationToken.ThrowIfCancellationRequested(); Task descriptionChangedTask; ClusterDescription description; lock (_descriptionLock) { descriptionChangedTask = _descriptionChangedTaskCompletionSource.Task; description = _description; } ThrowIfIncompatible(description); var connectedServers = description.Servers.Where(s => s.State == ServerState.Connected); var selectedServers = selector.SelectServers(description, connectedServers).ToList(); while (selectedServers.Count > 0) { var server = selectedServers.Count == 1 ? selectedServers[0] : __randomServerSelector.SelectServers(description, selectedServers).Single(); IClusterableServer selectedServer; if (TryGetServer(server.EndPoint, out selectedServer)) { return selectedServer; } selectedServers.Remove(server); } Invalidate(); await descriptionChangedTask.WithTimeout(slidingTimeout, cancellationToken); } }