/// <summary> /// Initializes a new instance of the <see cref="ClusterSelectedServerEvent" /> struct. /// </summary> /// <param name="clusterDescription">The cluster description.</param> /// <param name="serverSelector">The server selector.</param> /// <param name="selectedServer">The selected server.</param> /// <param name="duration">The duration of time it took to select the server.</param> public ClusterSelectedServerEvent(ClusterDescription clusterDescription, IServerSelector serverSelector, ServerDescription selectedServer, TimeSpan duration) { _clusterDescription = clusterDescription; _serverSelector = serverSelector; _selectedServer = selectedServer; _duration = duration; }
public async Task <IServer> SelectServerAsync(IServerSelector selector, CancellationToken cancellationToken) { ThrowIfDisposedOrNotOpen(); Ensure.IsNotNull(selector, nameof(selector)); using (var helper = new SelectServerHelper(this, selector)) { try { while (true) { var server = helper.SelectServer(); if (server != null) { return(server); } helper.WaitingForDescriptionToChange(); await WaitForDescriptionChangedAsync(helper.Selector, helper.Description, helper.DescriptionChangedTask, helper.TimeoutRemaining, cancellationToken).ConfigureAwait(false); } } catch (Exception ex) { helper.HandleException(ex); throw; } } }
// constructors /// <summary> /// Initializes a new instance of the <see cref="ClusterSettings"/> class. /// </summary> /// <param name="connectionMode">The connection mode.</param> /// <param name="endPoints">The end points.</param> /// <param name="kmsProviders">The kms providers.</param> /// <param name="localThreshold">The local threshold.</param> /// <param name="maxServerSelectionWaitQueueSize">Maximum size of the server selection wait queue.</param> /// <param name="replicaSetName">Name of the replica set.</param> /// <param name="serverSelectionTimeout">The server selection timeout.</param> /// <param name="preServerSelector">The pre server selector.</param> /// <param name="postServerSelector">The post server selector.</param> /// <param name="schemaMap">The schema map.</param> /// <param name="scheme">The connection string scheme.</param> public ClusterSettings( Optional <ClusterConnectionMode> connectionMode = default(Optional <ClusterConnectionMode>), Optional <IEnumerable <EndPoint> > endPoints = default(Optional <IEnumerable <EndPoint> >), Optional <IReadOnlyDictionary <string, IReadOnlyDictionary <string, object> > > kmsProviders = default(Optional <IReadOnlyDictionary <string, IReadOnlyDictionary <string, object> > >), Optional <TimeSpan> localThreshold = default, Optional <int> maxServerSelectionWaitQueueSize = default(Optional <int>), Optional <string> replicaSetName = default(Optional <string>), Optional <TimeSpan> serverSelectionTimeout = default(Optional <TimeSpan>), Optional <IServerSelector> preServerSelector = default(Optional <IServerSelector>), Optional <IServerSelector> postServerSelector = default(Optional <IServerSelector>), Optional <IReadOnlyDictionary <string, BsonDocument> > schemaMap = default(Optional <IReadOnlyDictionary <string, BsonDocument> >), Optional <ConnectionStringScheme> scheme = default(Optional <ConnectionStringScheme>)) { _connectionMode = connectionMode.WithDefault(ClusterConnectionMode.Automatic); _endPoints = Ensure.IsNotNull(endPoints.WithDefault(__defaultEndPoints), "endPoints").ToList(); _kmsProviders = kmsProviders.WithDefault(null); _localThreshold = Ensure.IsGreaterThanOrEqualToZero(localThreshold.WithDefault(TimeSpan.FromMilliseconds(15)), "localThreshold"); _maxServerSelectionWaitQueueSize = Ensure.IsGreaterThanOrEqualToZero(maxServerSelectionWaitQueueSize.WithDefault(500), "maxServerSelectionWaitQueueSize"); _replicaSetName = replicaSetName.WithDefault(null); _serverSelectionTimeout = Ensure.IsGreaterThanOrEqualToZero(serverSelectionTimeout.WithDefault(TimeSpan.FromSeconds(30)), "serverSelectionTimeout"); _preServerSelector = preServerSelector.WithDefault(null); _postServerSelector = postServerSelector.WithDefault(null); _scheme = scheme.WithDefault(ConnectionStringScheme.MongoDB); _schemaMap = schemaMap.WithDefault(null); }
// constructors /// <summary> /// Initializes a new instance of the <see cref="ReadPreferenceBinding" /> class. /// </summary> /// <param name="cluster">The cluster.</param> /// <param name="readPreference">The read preference.</param> /// <param name="session">The session.</param> public ReadPreferenceBinding(ICluster cluster, ReadPreference readPreference, ICoreSessionHandle session) { _cluster = Ensure.IsNotNull(cluster, nameof(cluster)); _readPreference = Ensure.IsNotNull(readPreference, nameof(readPreference)); _session = Ensure.IsNotNull(session, nameof(session)); _serverSelector = new ReadPreferenceServerSelector(readPreference); }
/// <summary> /// Initializes a new instance of the <see cref="ClusterSelectingServerFailedEvent" /> struct. /// </summary> /// <param name="clusterDescription">The cluster description.</param> /// <param name="serverSelector">The server selector.</param> /// <param name="exception">The exception.</param> /// <param name="operationId">The operation identifier.</param> public ClusterSelectingServerFailedEvent(ClusterDescription clusterDescription, IServerSelector serverSelector, Exception exception, long?operationId) { _clusterDescription = clusterDescription; _serverSelector = serverSelector; _exception = exception; _operationId = operationId; }
public SelectServerHelper(Cluster cluster, IServerSelector selector) { _cluster = cluster; _selector = DecorateSelector(selector); _stopwatch = Stopwatch.StartNew(); _timeoutAt = DateTime.UtcNow + _cluster.Settings.ServerSelectionTimeout; }
/// <summary> /// Initializes a new instance of the <see cref="ClusterSelectingServerEvent" /> struct. /// </summary> /// <param name="clusterDescription">The cluster description.</param> /// <param name="serverSelector">The server selector.</param> /// <param name="operationId">The operation identifier.</param> public ClusterSelectingServerEvent(ClusterDescription clusterDescription, IServerSelector serverSelector, long?operationId) { _clusterDescription = clusterDescription; _serverSelector = serverSelector; _operationId = operationId; _timestamp = DateTime.UtcNow; }
// constructors /// <summary> /// Initializes a new instance of the <see cref="ClusterSettings"/> class. /// </summary> /// <param name="connectionMode">The connection mode.</param> /// <param name="connectionModeSwitch">The connection mode switch.</param> /// <param name="directConnection">The directConnection.</param> /// <param name="endPoints">The end points.</param> /// <param name="kmsProviders">The kms providers.</param> /// <param name="localThreshold">The local threshold.</param> /// <param name="maxServerSelectionWaitQueueSize">Maximum size of the server selection wait queue.</param> /// <param name="replicaSetName">Name of the replica set.</param> /// <param name="serverSelectionTimeout">The server selection timeout.</param> /// <param name="preServerSelector">The pre server selector.</param> /// <param name="postServerSelector">The post server selector.</param> /// <param name="schemaMap">The schema map.</param> /// <param name="scheme">The connection string scheme.</param> public ClusterSettings( #pragma warning disable CS0618 // Type or member is obsolete Optional <ClusterConnectionMode> connectionMode = default(Optional <ClusterConnectionMode>), Optional <ConnectionModeSwitch> connectionModeSwitch = default, #pragma warning restore CS0618 // Type or member is obsolete Optional <bool?> directConnection = default, Optional <IEnumerable <EndPoint> > endPoints = default(Optional <IEnumerable <EndPoint> >), Optional <IReadOnlyDictionary <string, IReadOnlyDictionary <string, object> > > kmsProviders = default(Optional <IReadOnlyDictionary <string, IReadOnlyDictionary <string, object> > >), Optional <TimeSpan> localThreshold = default, Optional <int> maxServerSelectionWaitQueueSize = default(Optional <int>), Optional <string> replicaSetName = default(Optional <string>), Optional <TimeSpan> serverSelectionTimeout = default(Optional <TimeSpan>), Optional <IServerSelector> preServerSelector = default(Optional <IServerSelector>), Optional <IServerSelector> postServerSelector = default(Optional <IServerSelector>), Optional <IReadOnlyDictionary <string, BsonDocument> > schemaMap = default(Optional <IReadOnlyDictionary <string, BsonDocument> >), Optional <ConnectionStringScheme> scheme = default(Optional <ConnectionStringScheme>)) { #pragma warning disable CS0618 // Type or member is obsolete _connectionMode = connectionMode.WithDefault(ClusterConnectionMode.Automatic); _connectionModeSwitch = connectionModeSwitch.WithDefault(ConnectionModeSwitch.NotSet); #pragma warning restore CS0618 // Type or member is obsolete _directConnection = directConnection.WithDefault(null); _endPoints = Ensure.IsNotNull(endPoints.WithDefault(__defaultEndPoints), "endPoints").ToList(); _kmsProviders = kmsProviders.WithDefault(null); _localThreshold = Ensure.IsGreaterThanOrEqualToZero(localThreshold.WithDefault(TimeSpan.FromMilliseconds(15)), "localThreshold"); _maxServerSelectionWaitQueueSize = Ensure.IsGreaterThanOrEqualToZero(maxServerSelectionWaitQueueSize.WithDefault(500), "maxServerSelectionWaitQueueSize"); _replicaSetName = replicaSetName.WithDefault(null); _serverSelectionTimeout = Ensure.IsGreaterThanOrEqualToZero(serverSelectionTimeout.WithDefault(TimeSpan.FromSeconds(30)), "serverSelectionTimeout"); _preServerSelector = preServerSelector.WithDefault(null); _postServerSelector = postServerSelector.WithDefault(null); _scheme = scheme.WithDefault(ConnectionStringScheme.MongoDB); _schemaMap = schemaMap.WithDefault(null); ClusterConnectionModeHelper.EnsureConnectionModeValuesAreValid(_connectionMode, _connectionModeSwitch, _directConnection); }
/// <summary> /// Initializes a new instance of the <see cref="ClusterSelectingServerFailedEvent" /> struct. /// </summary> /// <param name="clusterDescription">The cluster description.</param> /// <param name="serverSelector">The server selector.</param> /// <param name="exception">The exception.</param> /// <param name="operationId">The operation identifier.</param> public ClusterSelectingServerFailedEvent(ClusterDescription clusterDescription, IServerSelector serverSelector, Exception exception, long? operationId) { _clusterDescription = clusterDescription; _serverSelector = serverSelector; _exception = exception; _operationId = operationId; }
internal static void SetStrategy(string name) { Sp = ServerSelectorManager.GetSelector(name); if (Sp is FixedServerSelector) { (Sp as FixedServerSelector).SetIndex(MyShadowsocksController.Config.Index); } }
private void WaitForDescriptionChanged(IServerSelector selector, ClusterDescription description, Task descriptionChangedTask, TimeSpan timeout, CancellationToken cancellationToken) { using (var helper = new WaitForDescriptionChangedHelper(this, selector, description, descriptionChangedTask, timeout, cancellationToken)) { var index = Task.WaitAny(helper.Tasks); helper.HandleCompletedTask(helper.Tasks[index]); } }
private async Task WaitForDescriptionChangedAsync(IServerSelector selector, ClusterDescription description, Task descriptionChangedTask, TimeSpan timeout, CancellationToken cancellationToken) { using (var helper = new WaitForDescriptionChangedHelper(this, selector, description, descriptionChangedTask, timeout, cancellationToken)) { var completedTask = await Task.WhenAny(helper.Tasks).ConfigureAwait(false); helper.HandleCompletedTask(completedTask); } }
/// <summary> /// Initializes a new instance of the <see cref="ClusterSelectedServerEvent" /> struct. /// </summary> /// <param name="clusterDescription">The cluster description.</param> /// <param name="serverSelector">The server selector.</param> /// <param name="selectedServer">The selected server.</param> /// <param name="duration">The duration of time it took to select the server.</param> /// <param name="operationId">The operation identifier.</param> public ClusterSelectedServerEvent(ClusterDescription clusterDescription, IServerSelector serverSelector, ServerDescription selectedServer, TimeSpan duration, long?operationId) { _clusterDescription = clusterDescription; _serverSelector = serverSelector; _selectedServer = selectedServer; _duration = duration; _operationId = operationId; _timestamp = DateTime.UtcNow; }
private string BuildTimeoutExceptionMessage(TimeSpan timeout, IServerSelector selector, ClusterDescription clusterDescription) { var ms = (int)Math.Round(timeout.TotalMilliseconds); return(string.Format( "A timeout occured after {0}ms selecting a server using {1}. Client view of cluster state is {2}.", ms.ToString(), selector.ToString(), clusterDescription.ToString())); }
public WaitForDescriptionChangedHelper(Cluster cluster, IServerSelector selector, ClusterDescription description, Task descriptionChangedTask, TimeSpan timeout, CancellationToken cancellationToken) { _cluster = cluster; _description = description; _selector = selector; _descriptionChangedTask = descriptionChangedTask; _cancellationToken = cancellationToken; _cancellationTaskCompletionSource = new TaskCompletionSource <bool>(); _cancellationTokenRegistration = cancellationToken.Register(() => _cancellationTaskCompletionSource.TrySetCanceled()); _timeoutCancellationTokenSource = new CancellationTokenSource(); _timeoutTask = Task.Delay(timeout, _timeoutCancellationTokenSource.Token); }
public SelectServerHelper(Cluster cluster, IServerSelector selector) { _cluster = cluster; _connectedServers = new List <IClusterableServer>(_cluster._description?.Servers?.Count ?? 1); _connectedServerDescriptions = new List <ServerDescription>(_connectedServers.Count); _operationCountServerSelector = new OperationsCountServerSelector(_connectedServers); _selector = DecorateSelector(selector); _stopwatch = Stopwatch.StartNew(); _timeoutAt = DateTime.UtcNow + _cluster.Settings.ServerSelectionTimeout; }
private IServer SelectServerAttempt(Cluster cluster, IServerSelector operationSelector, bool async) { if (async) { return(cluster .SelectServerAsync(operationSelector, CancellationToken.None) .GetAwaiter() .GetResult()); } else { return(cluster.SelectServer(operationSelector, CancellationToken.None)); } }
public IServer SelectServer(IServerSelector _, CancellationToken cancellationToken) { ThrowIfDisposed(); var index = Task.WaitAny(new[] { _serverReadyTaskCompletionSource.Task }, (int)_settings.ServerSelectionTimeout.TotalMilliseconds, cancellationToken); if (index != 0) { cancellationToken.ThrowIfCancellationRequested(); throw CreateTimeoutException(_description); // _description will contain dnsException } return(_server ?? throw new InvalidOperationException("The server must be created before usage.")); // should not be reached }
public async Task <IServer> SelectServerAsync(IServerSelector _, CancellationToken cancellationToken) { ThrowIfDisposed(); var timeoutTask = Task.Delay(_settings.ServerSelectionTimeout, cancellationToken); var triggeredTask = await Task.WhenAny(_serverReadyTaskCompletionSource.Task, timeoutTask).ConfigureAwait(false); if (triggeredTask == timeoutTask) { cancellationToken.ThrowIfCancellationRequested(); throw CreateTimeoutException(_description); // _description will contain dnsException } return(_server ?? throw new InvalidOperationException("The server must be created before usage.")); // should not be reached }
// constructors /// <summary> /// Initializes a new instance of the <see cref="ClusterSettings"/> class. /// </summary> /// <param name="connectionMode">The connection mode.</param> /// <param name="endPoints">The end points.</param> /// <param name="maxServerSelectionWaitQueueSize">Maximum size of the server selection wait queue.</param> /// <param name="replicaSetName">Name of the replica set.</param> /// <param name="serverSelectionTimeout">The server selection timeout.</param> /// <param name="preServerSelector">The pre server selector.</param> /// <param name="postServerSelector">The post server selector.</param> public ClusterSettings( Optional<ClusterConnectionMode> connectionMode = default(Optional<ClusterConnectionMode>), Optional<IEnumerable<EndPoint>> endPoints = default(Optional<IEnumerable<EndPoint>>), Optional<int> maxServerSelectionWaitQueueSize = default(Optional<int>), Optional<string> replicaSetName = default(Optional<string>), Optional<TimeSpan> serverSelectionTimeout = default(Optional<TimeSpan>), Optional<IServerSelector> preServerSelector = default(Optional<IServerSelector>), Optional<IServerSelector> postServerSelector = default(Optional<IServerSelector>)) { _connectionMode = connectionMode.WithDefault(ClusterConnectionMode.Automatic); _endPoints = Ensure.IsNotNull(endPoints.WithDefault(__defaultEndPoints), "endPoints").ToList(); _maxServerSelectionWaitQueueSize = Ensure.IsGreaterThanOrEqualToZero(maxServerSelectionWaitQueueSize.WithDefault(500), "maxServerSelectionWaitQueueSize"); _replicaSetName = replicaSetName.WithDefault(null); _serverSelectionTimeout = Ensure.IsGreaterThanOrEqualToZero(serverSelectionTimeout.WithDefault(TimeSpan.FromSeconds(30)), "serverSelectionTimeout"); _preServerSelector = preServerSelector.WithDefault(null); _postServerSelector = postServerSelector.WithDefault(null); }
// constructors public ClusterSettings( Optional <ClusterConnectionMode> connectionMode = default(Optional <ClusterConnectionMode>), Optional <IEnumerable <EndPoint> > endPoints = default(Optional <IEnumerable <EndPoint> >), Optional <int> maxServerSelectionWaitQueueSize = default(Optional <int>), Optional <string> replicaSetName = default(Optional <string>), Optional <TimeSpan> serverSelectionTimeout = default(Optional <TimeSpan>), Optional <IServerSelector> preServerSelector = default(Optional <IServerSelector>), Optional <IServerSelector> postServerSelector = default(Optional <IServerSelector>)) { _connectionMode = connectionMode.WithDefault(ClusterConnectionMode.Automatic); _endPoints = Ensure.IsNotNull(endPoints.WithDefault(__defaultEndPoints), "endPoints").ToList(); _maxServerSelectionWaitQueueSize = Ensure.IsGreaterThanOrEqualToZero(maxServerSelectionWaitQueueSize.WithDefault(500), "maxServerSelectionWaitQueueSize"); _replicaSetName = replicaSetName.WithDefault(null); _serverSelectionTimeout = Ensure.IsInfiniteOrGreaterThanOrEqualToZero(serverSelectionTimeout.WithDefault(TimeSpan.FromSeconds(30)), "serverSelectionTimeout"); _preServerSelector = preServerSelector.WithDefault(null); _postServerSelector = postServerSelector.WithDefault(null); }
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); } }
public static IServer SelectServerAndPinIfNeeded( this ICluster cluster, ICoreSessionHandle session, IServerSelector selector, CancellationToken cancellationToken) { var pinnedServer = GetPinnedServerIfValid(cluster, session); if (pinnedServer != null) { return(pinnedServer); } // Server selection also updates the cluster type, allowing us to to determine if the server // should be pinned. var server = cluster.SelectServer(selector, cancellationToken); PinServerIfNeeded(cluster, session, server); return(server); }
private IServerSelector DecorateSelector(IServerSelector selector) { var settings = _cluster.Settings; var allSelectors = new List <IServerSelector>(); if (settings.PreServerSelector != null) { allSelectors.Add(settings.PreServerSelector); } allSelectors.Add(selector); if (settings.PostServerSelector != null) { allSelectors.Add(settings.PostServerSelector); } allSelectors.Add(_cluster._latencyLimitingServerSelector); return(new CompositeServerSelector(allSelectors)); }
public RedisGroup(string groupName, int poolSize, RedisSettings[] settings, IServerSelector selector = null) : this() { GroupName = groupName; PoolSize = poolSize; foreach (var setting in settings) { if (setting.Master) { MasterSettings.Add(setting); } else { SlaveSettings.Add(setting); } } if (SlaveSettings.Count == 0) { SlaveSettings = MasterSettings; } _serverSelector = selector ?? new SimpleHashingSelector(); }
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)); }
private async Task WaitForDescriptionChangedAsync(IServerSelector selector, ClusterDescription description, Task descriptionChangedTask, TimeSpan timeout, CancellationToken cancellationToken) { var cancellationTaskCompletionSource = new TaskCompletionSource <bool>(); using (cancellationToken.Register(() => cancellationTaskCompletionSource.TrySetCanceled())) using (var timeoutCancellationTokenSource = new CancellationTokenSource()) { var timeoutTask = Task.Delay(timeout, timeoutCancellationTokenSource.Token); var completedTask = await Task.WhenAny(descriptionChangedTask, timeoutTask, cancellationTaskCompletionSource.Task).ConfigureAwait(false); if (completedTask == timeoutTask) { ThrowTimeoutException(selector, description); } timeoutCancellationTokenSource.Cancel(); if (completedTask == cancellationTaskCompletionSource.Task) { cancellationToken.ThrowIfCancellationRequested(); } await descriptionChangedTask.ConfigureAwait(false); // propagate exceptions } }
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(); } } }
// static methods public static IServer SelectServer(this ICluster cluster, IServerSelector selector = null, CancellationToken cancellationToken = default(CancellationToken)) { Ensure.IsNotNull(cluster, "cluster"); return cluster.SelectServerAsync(selector, cancellationToken).GetAwaiter().GetResult(); }
// constructors /// <summary> /// Initializes a new instance of the <see cref="ReadPreferenceBinding"/> class. /// </summary> /// <param name="cluster">The cluster.</param> /// <param name="readPreference">The read preference.</param> public ReadPreferenceBinding(ICluster cluster, ReadPreference readPreference) { _cluster = Ensure.IsNotNull(cluster, "cluster"); _readPreference = Ensure.IsNotNull(readPreference, "readPreference"); _serverSelector = new ReadPreferenceServerSelector(readPreference); }
public Task<IServer> SelectServerAsync(IServerSelector selector, CancellationToken cancellationToken) { throw new NotImplementedException(); }
/// <summary> /// Initializes a new instance of the <see cref="ClusterSelectingServerEvent" /> struct. /// </summary> /// <param name="clusterDescription">The cluster description.</param> /// <param name="serverSelector">The server selector.</param> /// <param name="operationId">The operation identifier.</param> public ClusterSelectingServerEvent(ClusterDescription clusterDescription, IServerSelector serverSelector, long? operationId) { _clusterDescription = clusterDescription; _serverSelector = serverSelector; _operationId = operationId; }
/// <summary> /// Initializes a new instance of the <see cref="ClusterSelectingServerFailedEvent" /> struct. /// </summary> /// <param name="clusterDescription">The cluster description.</param> /// <param name="serverSelector">The server selector.</param> /// <param name="exception">The exception.</param> public ClusterSelectingServerFailedEvent(ClusterDescription clusterDescription, IServerSelector serverSelector, Exception exception) { _clusterDescription = clusterDescription; _serverSelector = serverSelector; _exception = exception; }
private void ThrowTimeoutException(IServerSelector selector, ClusterDescription description) { var message = BuildTimeoutExceptionMessage(_settings.ServerSelectionTimeout, selector, description); throw new TimeoutException(message); }
public IServer SelectServer(IServerSelector selector, CancellationToken cancellationToken) { throw new NotImplementedException(); }
public RedisGroup(string groupName, RedisSettings[] settings, IServerSelector selector = null) { this.GroupName = groupName; this.Settings = settings; this.serverSelector = selector ?? new SimpleHashingSelector(); }
/// <summary> /// Initializes a new instance of the <see cref="ClusterSelectingServerEvent" /> struct. /// </summary> /// <param name="clusterDescription">The cluster description.</param> /// <param name="serverSelector">The server selector.</param> public ClusterSelectingServerEvent(ClusterDescription clusterDescription, IServerSelector serverSelector) { _clusterDescription = clusterDescription; _serverSelector = serverSelector; }
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(); } } }
public async Task PoolClearedError_write_retryablity_test([Values(false, true)] bool async) { RequireServer.Check() .Supports(Feature.FailPointsBlockConnection) .ClusterTypes(ClusterType.ReplicaSet, ClusterType.Sharded); var heartbeatInterval = TimeSpan.FromMilliseconds(50); var eventsWaitTimeout = TimeSpan.FromMilliseconds(5000); var failPointCommand = BsonDocument.Parse( $@"{{ configureFailPoint : 'failCommand', mode : {{ 'times' : 1 }}, data : {{ failCommands : [ 'insert' ], errorCode : 91, blockConnection: true, blockTimeMS: 1000, errorLabels: [""RetryableWriteError""] }} }}"); IServerSelector failPointSelector = WritableServerSelector.Instance; var settings = DriverTestConfiguration.GetClientSettings(); if (CoreTestConfiguration.Cluster.Description.Type == ClusterType.Sharded) { var serverAddress = settings.Servers.First(); settings.Servers = new[] { serverAddress }; // set settings.DirectConnection = true after removing obsolete ConnectionMode #pragma warning disable CS0618 // Type or member is obsolete settings.ConnectionMode = ConnectionMode.Direct; #pragma warning restore CS0618 // Type or member is obsolete failPointSelector = new EndPointServerSelector(new DnsEndPoint(serverAddress.Host, serverAddress.Port)); } settings.MaxConnectionPoolSize = 1; settings.RetryWrites = true; var eventCapturer = new EventCapturer() .Capture <ConnectionPoolClearedEvent>() .Capture <ConnectionPoolCheckedOutConnectionEvent>() .Capture <ConnectionPoolCheckingOutConnectionFailedEvent>() .CaptureCommandEvents("insert"); var failpointServer = DriverTestConfiguration.Client.Cluster.SelectServer(failPointSelector, default); using var failPoint = FailPoint.Configure(failpointServer, NoCoreSession.NewHandle(), failPointCommand); using var client = CreateClient(settings, eventCapturer, heartbeatInterval); var database = client.GetDatabase(DriverTestConfiguration.DatabaseNamespace.DatabaseName); var collection = database.GetCollection <BsonDocument>(DriverTestConfiguration.CollectionNamespace.CollectionName); eventCapturer.Clear(); if (async) { await ThreadingUtilities.ExecuteTasksOnNewThreads(2, async _ => { await collection.InsertOneAsync(new BsonDocument("x", 1)); }); } else { ThreadingUtilities.ExecuteOnNewThreads(2, _ => { collection.InsertOne(new BsonDocument("x", 1)); }); } // wait for 2 CommandSucceededEvent events, meaning that all other events should be received eventCapturer.WaitForOrThrowIfTimeout( events => events.OfType <CommandSucceededEvent>().Count() == 2, eventsWaitTimeout); eventCapturer.Events.OfType <CommandStartedEvent>().Count().Should().Be(3); eventCapturer.Events.OfType <CommandFailedEvent>().Count().Should().Be(1); eventCapturer.Events.OfType <CommandSucceededEvent>().Count().Should().Be(2); eventCapturer.Events.OfType <ConnectionPoolClearedEvent>().Count().Should().Be(1); eventCapturer.Events.OfType <ConnectionPoolCheckedOutConnectionEvent>().Count().Should().Be(3); eventCapturer.Events.OfType <ConnectionPoolCheckingOutConnectionFailedEvent>().Count().Should().Be(1); }
private string BuildTimeoutExceptionMessage(TimeSpan timeout, IServerSelector selector, ClusterDescription clusterDescription) { var ms = (int)Math.Round(timeout.TotalMilliseconds); return string.Format( "A timeout occured after {0}ms selecting a server using {1}. Client view of cluster state is {2}.", ms.ToString(), selector.ToString(), clusterDescription.ToString()); }
private async Task WaitForDescriptionChangedAsync(IServerSelector selector, ClusterDescription description, Task descriptionChangedTask, TimeSpan timeout, CancellationToken cancellationToken) { var cancellationTaskCompletionSource = new TaskCompletionSource<bool>(); using (cancellationToken.Register(() => cancellationTaskCompletionSource.TrySetCanceled())) using (var timeoutCancellationTokenSource = new CancellationTokenSource()) { var timeoutTask = Task.Delay(timeout, timeoutCancellationTokenSource.Token); var completedTask = await Task.WhenAny(descriptionChangedTask, timeoutTask, cancellationTaskCompletionSource.Task).ConfigureAwait(false); if (completedTask == timeoutTask) { ThrowTimeoutException(selector, description); } timeoutCancellationTokenSource.Cancel(); if (completedTask == cancellationTaskCompletionSource.Task) { cancellationToken.ThrowIfCancellationRequested(); } await descriptionChangedTask.ConfigureAwait(false); // propagate exceptions } }
public async Task<IServer> SelectServerAsync(IServerSelector selector, CancellationToken cancellationToken) { ThrowIfDisposedOrNotOpen(); Ensure.IsNotNull(selector, nameof(selector)); using (var helper = new SelectServerHelper(this, selector)) { try { while (true) { var server = helper.SelectServer(); if (server != null) { return server; } helper.WaitingForDescriptionToChange(); await WaitForDescriptionChangedAsync(helper.Selector, helper.Description, helper.DescriptionChangedTask, helper.TimeoutRemaining, cancellationToken).ConfigureAwait(false); } } catch (Exception ex) { helper.HandleException(ex); throw; } } }
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); } }
public WaitForDescriptionChangedHelper(Cluster cluster, IServerSelector selector, ClusterDescription description, Task descriptionChangedTask , TimeSpan timeout, CancellationToken cancellationToken) { _cluster = cluster; _description = description; _selector = selector; _descriptionChangedTask = descriptionChangedTask; _cancellationToken = cancellationToken; _cancellationTaskCompletionSource = new TaskCompletionSource<bool>(); _cancellationTokenRegistration = cancellationToken.Register(() => _cancellationTaskCompletionSource.TrySetCanceled()); _timeoutCancellationTokenSource = new CancellationTokenSource(); _timeoutTask = Task.Delay(timeout, _timeoutCancellationTokenSource.Token); }
private IServerSelector DecorateSelector(IServerSelector selector) { var settings = _cluster.Settings; 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); } return new CompositeServerSelector(allSelectors); } return selector; }