internal ControlConnection(Cluster cluster, IEnumerable<IPAddress> clusterEndpoints, Policies policies, ProtocolOptions protocolOptions, PoolingOptions poolingOptions, SocketOptions socketOptions, ClientOptions clientOptions, IAuthProvider authProvider, IAuthInfoProvider authInfoProvider) { _cluster = cluster; _reconnectionSchedule = _reconnectionPolicy.NewSchedule(); _reconnectionTimer = new Timer(ReconnectionClb, null, Timeout.Infinite, Timeout.Infinite); var config = new Configuration ( policies, protocolOptions, poolingOptions, socketOptions, clientOptions, authProvider, authInfoProvider, new QueryOptions() ); _session = new Session(cluster, config, "", ControlConnectionProtocolVersion); }
internal ControlConnection(byte initialProtocolVersion, Configuration config, Metadata metadata) { Metadata = metadata; _reconnectionSchedule = _reconnectionPolicy.NewSchedule(); _reconnectionTimer = new Timer(_ => Refresh(true), null, Timeout.Infinite, Timeout.Infinite); _config = config; ProtocolVersion = initialProtocolVersion; }
/// <summary> /// Asynchronously starts to create a new connection (if its not already being created). /// A <c>null</c> schedule signals that the pool is not reconnecting but growing to the expected size. /// </summary> /// <param name="schedule"></param> private void StartCreatingConnection(IReconnectionSchedule schedule) { var count = _connections.Count; if (count >= _expectedConnectionLength) { return; } if (schedule != null && schedule != _reconnectionSchedule) { // There's another reconnection schedule, leave it return; } CreateOrScheduleReconnectAsync(schedule).Forget(); }
internal ControlConnection(Cluster cluster, IEnumerable<IPAddress> clusterEndpoints, Policies policies, ProtocolOptions protocolOptions, PoolingOptions poolingOptions, SocketOptions socketOptions, ClientOptions clientOptions, IAuthInfoProvider authProvider) { this._cluster = cluster; this._reconnectionSchedule = _reconnectionPolicy.NewSchedule(); this._reconnectionTimer = new Timer(ReconnectionClb, null, Timeout.Infinite, Timeout.Infinite); _session = new Session(cluster, policies, protocolOptions, poolingOptions, socketOptions, clientOptions, authProvider, "", false); }
public HostConnectionPool(Host host, Configuration config, Serializer serializer, IObserverFactory observerFactory) { _host = host; _host.Down += OnHostDown; _host.Up += OnHostUp; _host.DistanceChanged += OnDistanceChanged; _config = config ?? throw new ArgumentNullException(nameof(config)); _maxRequestsPerConnection = config .GetPoolingOptions(serializer.ProtocolVersion) .GetMaxRequestsPerConnection(); _serializer = serializer; _observerFactory = observerFactory; _timer = config.Timer; _reconnectionSchedule = config.Policies.ReconnectionPolicy.NewSchedule(); _expectedConnectionLength = 1; }
internal ControlConnection(Cluster cluster, IEnumerable <IPAddress> clusterEndpoints, Policies policies, ProtocolOptions protocolOptions, PoolingOptions poolingOptions, SocketOptions socketOptions, ClientOptions clientOptions, IAuthProvider authProvider, IAuthInfoProvider authInfoProvider, int binaryProtocolVersion) { _cluster = cluster; _reconnectionSchedule = _reconnectionPolicy.NewSchedule(); _reconnectionTimer = new Timer(ReconnectionClb, null, Timeout.Infinite, Timeout.Infinite); _session = new Session(cluster, policies, protocolOptions, poolingOptions, socketOptions, clientOptions, authProvider, authInfoProvider, "", binaryProtocolVersion); }
/// <summary> /// Asynchronously starts to create a new connection (if its not already being created). /// A <c>null</c> schedule signals that the pool is not reconnecting but growing to the expected size. /// </summary> /// <param name="schedule"></param> private void StartCreatingConnection(IReconnectionSchedule schedule) { var count = _connections.Count; if (count >= _expectedConnectionLength) { return; } if (schedule != null && schedule != _reconnectionSchedule) { // There's another reconnection schedule, leave it return; } CreateOpenConnection(false).ContinueWith(t => { if (t.Status == TaskStatus.RanToCompletion) { StartCreatingConnection(null); _host.BringUpIfDown(); return; } t.Exception?.Handle(_ => true); // The connection could not be opened if (IsClosing) { // don't mind, the pool is not supposed to be open return; } if (schedule == null) { // As it failed, we need a new schedule for the following attempts schedule = _config.Policies.ReconnectionPolicy.NewSchedule(); _reconnectionSchedule = schedule; } if (schedule != _reconnectionSchedule) { // There's another reconnection schedule, leave it return; } OnConnectionClosing(); }, TaskContinuationOptions.ExecuteSynchronously); }
internal Task <bool> Reconnect() { //If there is another thread reconnecting, use the same task var tcs = new TaskCompletionSource <bool>(); var currentTask = Interlocked.CompareExchange(ref _reconnectTask, tcs.Task, null); if (currentTask != null) { return(currentTask); } Unsubscribe(); Connect(false).ContinueWith(t => { if (t.Exception != null) { Interlocked.Exchange(ref _reconnectTask, null); tcs.TrySetException(t.Exception.InnerException); var delay = _reconnectionSchedule.NextDelayMs(); _reconnectionTimer.Change(delay, Timeout.Infinite); _logger.Error("ControlConnection was not able to reconnect: " + t.Exception.InnerException); return; } try { RefreshNodeList(); Metadata.RefreshKeyspaces(false); _reconnectionSchedule = _reconnectionPolicy.NewSchedule(); tcs.TrySetResult(true); Interlocked.Exchange(ref _reconnectTask, null); _logger.Info("ControlConnection reconnected to host {0}", _host.Address); } catch (Exception ex) { Interlocked.Exchange(ref _reconnectTask, null); _logger.Error("There was an error when trying to refresh the ControlConnection", ex); _reconnectionTimer.Change(_reconnectionSchedule.NextDelayMs(), Timeout.Infinite); tcs.TrySetException(ex); } }); return(tcs.Task); }
private async Task CreateOrScheduleReconnectAsync(IReconnectionSchedule schedule) { if (IsClosing) { return; } try { var t = await CreateOpenConnection(false, schedule != null).ConfigureAwait(false); StartCreatingConnection(null); _host.BringUpIfDown(); } catch (Exception) { // The connection could not be opened if (IsClosing) { // don't mind, the pool is not supposed to be open return; } if (schedule == null) { // As it failed, we need a new schedule for the following attempts schedule = _config.Policies.ReconnectionPolicy.NewSchedule(); _reconnectionSchedule = schedule; } if (schedule != _reconnectionSchedule) { // There's another reconnection schedule, leave it return; } OnConnectionClosing(); } }
private void SetNewConnectionTimeout(IReconnectionSchedule schedule) { if (schedule != null && _reconnectionSchedule != schedule) { // There's another reconnection schedule, leave it return; } HashedWheelTimer.ITimeout timeout = null; if (schedule != null) { // Schedule the creation var delay = schedule.NextDelayMs(); Logger.Info("Scheduling reconnection from #{0} to {1} in {2}ms", GetHashCode(), _host.Address, delay); timeout = _timer.NewTimeout(_ => Task.Run(() => StartCreatingConnection(schedule)), null, delay); } CancelNewConnectionTimeout(timeout); if (schedule == null) { // Start creating immediately after de-scheduling the timer Logger.Info("Starting reconnection from pool #{0} to {1}", GetHashCode(), _host.Address); StartCreatingConnection(null); } }
private async Task Refresh() { if (Interlocked.Increment(ref _refreshCounter) != 1) { //Only one refresh at a time Interlocked.Decrement(ref _refreshCounter); return; } var reconnect = false; try { await RefreshNodeList().ConfigureAwait(false); await _metadata.RefreshKeyspaces(false).ConfigureAwait(false); _reconnectionSchedule = _reconnectionPolicy.NewSchedule(); } catch (SocketException ex) { _logger.Error("There was a SocketException when trying to refresh the ControlConnection", ex); reconnect = true; } catch (Exception ex) { _logger.Error("There was an error when trying to refresh the ControlConnection", ex); } finally { Interlocked.Decrement(ref _refreshCounter); } if (reconnect) { await Reconnect().ConfigureAwait(false); } }
public Host(IPEndPoint address, IReconnectionPolicy reconnectionPolicy) { Address = address; _reconnectionPolicy = reconnectionPolicy; _reconnectionSchedule = reconnectionPolicy.NewSchedule(); }
public Host(IPAddress address, IReconnectionPolicy reconnectionPolicy) { this._address = address; this._reconnectionPolicy = reconnectionPolicy; this._reconnectionSchedule = reconnectionPolicy.NewSchedule(); }
public bool BringUpIfDown() { _reconnectionSchedule = _reconnectionPolicy.NewSchedule(); if (!_isUpNow) { _isUpNow = true; return true; } return false; }
internal void Refresh() { if (Interlocked.Increment(ref _refreshCounter) != 1) { //Only one refresh at a time Interlocked.Decrement(ref _refreshCounter); return; } var reconnect = false; try { RefreshNodeList(); TaskHelper.WaitToComplete(_metadata.RefreshKeyspaces(false), MetadataAbortTimeout); _reconnectionSchedule = _reconnectionPolicy.NewSchedule(); } catch (SocketException ex) { _logger.Error("There was a SocketException when trying to refresh the ControlConnection", ex); reconnect = true; } catch (Exception ex) { _logger.Error("There was an error when trying to refresh the ControlConnection", ex); } finally { Interlocked.Decrement(ref _refreshCounter); } if (reconnect) { Reconnect(); } }
internal Task <bool> Reconnect() { //If there is another thread reconnecting, use the same task var tcs = new TaskCompletionSource <bool>(); var currentTask = Interlocked.CompareExchange(ref _reconnectTask, tcs.Task, null); if (currentTask != null) { return(currentTask); } Unsubscribe(); Connect(false).ContinueWith(t => { if (Interlocked.Read(ref _isShutdown) > 0L) { if (t.Exception != null) { t.Exception.Handle(e => true); } return; } if (t.Exception != null) { t.Exception.Handle(e => true); Interlocked.Exchange(ref _reconnectTask, null); tcs.TrySetException(t.Exception.InnerException); var delay = _reconnectionSchedule.NextDelayMs(); _logger.Error("ControlConnection was not able to reconnect: " + t.Exception.InnerException); try { _reconnectionTimer.Change((int)delay, Timeout.Infinite); } catch (ObjectDisposedException) { //Control connection is being disposed } return; } try { RefreshNodeList(); TaskHelper.WaitToComplete(_metadata.RefreshKeyspaces(false), MetadataAbortTimeout); _reconnectionSchedule = _reconnectionPolicy.NewSchedule(); tcs.TrySetResult(true); Interlocked.Exchange(ref _reconnectTask, null); _logger.Info("ControlConnection reconnected to host {0}", _host.Address); } catch (Exception ex) { Interlocked.Exchange(ref _reconnectTask, null); _logger.Error("There was an error when trying to refresh the ControlConnection", ex); tcs.TrySetException(ex); try { _reconnectionTimer.Change((int)_reconnectionSchedule.NextDelayMs(), Timeout.Infinite); } catch (ObjectDisposedException) { //Control connection is being disposed } } }); return(tcs.Task); }
internal async Task <bool> Reconnect() { var tcs = new TaskCompletionSource <bool>(); var currentTask = Interlocked.CompareExchange(ref _reconnectTask, tcs.Task, null); if (currentTask != null) { // If there is another thread reconnecting, use the same task return(await currentTask.ConfigureAwait(false)); } Unsubscribe(); try { await Connect(false).ConfigureAwait(false); } catch (Exception ex) { // It failed to reconnect, schedule the timer for next reconnection and let go. Interlocked.Exchange(ref _reconnectTask, null).Forget(); tcs.TrySetException(ex); var delay = _reconnectionSchedule.NextDelayMs(); _logger.Error("ControlConnection was not able to reconnect: " + ex); try { _reconnectionTimer.Change((int)delay, Timeout.Infinite); } catch (ObjectDisposedException) { //Control connection is being disposed } // It will throw the same exception that it was set in the TCS throw; } if (Interlocked.Read(ref _isShutdown) > 0L) { return(false); } try { await RefreshNodeList().ConfigureAwait(false); TaskHelper.WaitToComplete(_metadata.RefreshKeyspaces(false), MetadataAbortTimeout); _reconnectionSchedule = _reconnectionPolicy.NewSchedule(); tcs.TrySetResult(true); Interlocked.Exchange(ref _reconnectTask, null).Forget(); _logger.Info("ControlConnection reconnected to host {0}", _host.Address); } catch (Exception ex) { Interlocked.Exchange(ref _reconnectTask, null).Forget(); _logger.Error("There was an error when trying to refresh the ControlConnection", ex); tcs.TrySetException(ex); try { _reconnectionTimer.Change((int)_reconnectionSchedule.NextDelayMs(), Timeout.Infinite); } catch (ObjectDisposedException) { //Control connection is being disposed } } return(await tcs.Task.ConfigureAwait(false)); }
public Host(IPAddress address, IReconnectionPolicy reconnectionPolicy) { _address = address; _reconnectionPolicy = reconnectionPolicy; _reconnectionSchedule = reconnectionPolicy.NewSchedule(); }
internal ControlConnection(byte initialProtocolVersion, Configuration config, Metadata metadata) { _metadata = metadata; _reconnectionPolicy = config.Policies.ReconnectionPolicy; _reconnectionSchedule = _reconnectionPolicy.NewSchedule(); _reconnectionTimer = new Timer(_ => Reconnect(), null, Timeout.Infinite, Timeout.Infinite); _config = config; _serializer = new Serializer(initialProtocolVersion, config.TypeSerializers); }
internal Task<bool> Reconnect() { //If there is another thread reconnecting, use the same task var tcs = new TaskCompletionSource<bool>(); var currentTask = Interlocked.CompareExchange(ref _reconnectTask, tcs.Task, null); if (currentTask != null) { return currentTask; } Unsubscribe(); Connect(false).ContinueWith(t => { if (Thread.VolatileRead(ref _isShutdown) > 0) { if (t.Exception != null) { t.Exception.Handle(e => true); } return; } if (t.Exception != null) { t.Exception.Handle(e => true); Interlocked.Exchange(ref _reconnectTask, null); tcs.TrySetException(t.Exception.InnerException); var delay = _reconnectionSchedule.NextDelayMs(); _logger.Error("ControlConnection was not able to reconnect: " + t.Exception.InnerException); try { _reconnectionTimer.Change(delay, Timeout.Infinite); } catch (ObjectDisposedException) { //Control connection is being disposed } return; } try { RefreshNodeList(); TaskHelper.WaitToComplete(_metadata.RefreshKeyspaces(false), MetadataAbortTimeout); _reconnectionSchedule = _reconnectionPolicy.NewSchedule(); tcs.TrySetResult(true); Interlocked.Exchange(ref _reconnectTask, null); _logger.Info("ControlConnection reconnected to host {0}", _host.Address); } catch (Exception ex) { Interlocked.Exchange(ref _reconnectTask, null); _logger.Error("There was an error when trying to refresh the ControlConnection", ex); tcs.TrySetException(ex); try { _reconnectionTimer.Change(_reconnectionSchedule.NextDelayMs(), Timeout.Infinite); } catch (ObjectDisposedException) { //Control connection is being disposed } } }); return tcs.Task; }
internal void Refresh(bool reconnect = false, bool throwExceptions = false) { lock (_refreshLock) { try { if (reconnect) { Unsubscribe(); Connect(false); SubscribeEventHandlers(); } RefreshNodeList(); Metadata.RefreshKeyspaces(false); _reconnectionSchedule = _reconnectionPolicy.NewSchedule(); } catch (Exception ex) { _logger.Error("There was an error when trying to refresh the ControlConnection", ex); _reconnectionTimer.Change(_reconnectionSchedule.NextDelayMs(), Timeout.Infinite); if (throwExceptions) { throw; } } } }
private void CheckConnectionDown(IPAddress endpoint) { if (_hostsIter != null && _hostsIter.Current.Address == endpoint) { _reconnectionSchedule = _reconnectionPolicy.NewSchedule(); Go(false); } }
private void CheckConnectionUp(IPAddress endpoint) { if (_isDiconnected) { _reconnectionSchedule = _reconnectionPolicy.NewSchedule(); Go(true); } }
public void BringUpIfDown() { this._reconnectionSchedule = _reconnectionPolicy.NewSchedule(); _isUpNow = true; }
internal ControlConnection(ICluster cluster, Metadata metadata) { Metadata = metadata; _reconnectionSchedule = _reconnectionPolicy.NewSchedule(); _reconnectionTimer = new Timer(_ => Refresh(true), null, Timeout.Infinite, Timeout.Infinite); _config = cluster.Configuration; }