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 void RunTestDefinition(BsonDocument definition) { var clusterDescription = BuildClusterDescription((BsonDocument)definition["topology_description"]); IServerSelector selector; if (definition["operation"].ToString() == "write") { selector = WritableServerSelector.Instance; } else { selector = BuildServerSelector((BsonDocument)definition["read_preference"]); } var suitableServers = BuildServerDescriptions((BsonArray)definition["suitable_servers"]).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"]).ToList(); selectedServers = selector.SelectServers(clusterDescription, clusterDescription.Servers).ToList(); AssertServers(inLatencyWindowServers, selectedServers); }
public async Task <IServer> SelectServerAsync(IServerSelector selector, CancellationToken cancellationToken) { ThrowIfDisposedOrNotOpen(); Ensure.IsNotNull(selector, "selector"); var timeoutAt = DateTime.UtcNow + _settings.ServerSelectionTimeout; var serverSelectionWaitQueueEntered = false; if (_settings.PreServerSelector != null || _settings.PostServerSelector != null) { var allSelectors = new List <IServerSelector>(); if (_settings.PreServerSelector != null) { allSelectors.Add(_settings.PreServerSelector); } allSelectors.Add(selector); if (_settings.PostServerSelector != null) { allSelectors.Add(_settings.PostServerSelector); } selector = new CompositeServerSelector(allSelectors); } ClusterDescription description = null; try { var stopwatch = Stopwatch.StartNew(); while (true) { cancellationToken.ThrowIfCancellationRequested(); Task descriptionChangedTask; lock (_descriptionLock) { descriptionChangedTask = _descriptionChangedTaskCompletionSource.Task; description = _description; } if (!serverSelectionWaitQueueEntered && _selectingServerEventHandler != null) { // this is our first time through... _selectingServerEventHandler(new ClusterSelectingServerEvent( description, selector)); } 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)) { stopwatch.Stop(); if (_selectedServerEventHandler != null) { _selectedServerEventHandler(new ClusterSelectedServerEvent( description, selector, server, stopwatch.Elapsed)); } return(selectedServer); } selectedServers.Remove(server); } if (!serverSelectionWaitQueueEntered) { EnterServerSelectionWaitQueue(); serverSelectionWaitQueueEntered = true; } var timeoutRemaining = timeoutAt - DateTime.UtcNow; if (timeoutRemaining <= TimeSpan.Zero) { ThrowTimeoutException(selector, description); } await WaitForDescriptionChangedAsync(selector, description, descriptionChangedTask, timeoutRemaining, cancellationToken).ConfigureAwait(false); } } catch (Exception ex) { if (_selectingServerFailedEventHandler != null) { _selectingServerFailedEventHandler(new ClusterSelectingServerFailedEvent( description, selector, ex)); } throw; } finally { if (serverSelectionWaitQueueEntered) { ExitServerSelectionWaitQueue(); } } }