Пример #1
0
            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);
        }
Пример #3
0
        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);
            }
        }
Пример #4
0
        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));
        }
Пример #5
0
        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));
        }
Пример #6
0
        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();
                }
            }
        }
Пример #7
0
            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();
        }
Пример #9
0
        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);
            }
        }