예제 #1
0
        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;
 }
예제 #3
0
        /// <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();
        }
예제 #4
0
        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);
        }
예제 #5
0
 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;
 }
예제 #6
0
        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);
        }
예제 #7
0
        /// <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);
        }
예제 #8
0
        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);
        }
예제 #9
0
        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();
            }
        }
예제 #10
0
 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);
     }
 }
예제 #11
0
        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);
            }
        }
예제 #12
0
 public Host(IPEndPoint address, IReconnectionPolicy reconnectionPolicy)
 {
     Address               = address;
     _reconnectionPolicy   = reconnectionPolicy;
     _reconnectionSchedule = reconnectionPolicy.NewSchedule();
 }
예제 #13
0
 public Host(IPAddress address, IReconnectionPolicy reconnectionPolicy)
 {
     this._address = address;
     this._reconnectionPolicy = reconnectionPolicy;
     this._reconnectionSchedule = reconnectionPolicy.NewSchedule();
 }
예제 #14
0
 public bool BringUpIfDown()
 {
     _reconnectionSchedule = _reconnectionPolicy.NewSchedule();
     if (!_isUpNow)
     {
         _isUpNow = true;
         return true;
     }
     return false;
 }
예제 #15
0
 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();
     }
 }
예제 #16
0
        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);
        }
예제 #17
0
 public Host(IPEndPoint address, IReconnectionPolicy reconnectionPolicy)
 {
     Address = address;
     _reconnectionPolicy = reconnectionPolicy;
     _reconnectionSchedule = reconnectionPolicy.NewSchedule();
 }
예제 #18
0
        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));
        }
예제 #19
0
 public Host(IPAddress address, IReconnectionPolicy reconnectionPolicy)
 {
     _address              = address;
     _reconnectionPolicy   = reconnectionPolicy;
     _reconnectionSchedule = reconnectionPolicy.NewSchedule();
 }
예제 #20
0
 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);
 }
예제 #21
0
 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);
     }
 }
예제 #25
0
 public void BringUpIfDown()
 {
     this._reconnectionSchedule = _reconnectionPolicy.NewSchedule();
     _isUpNow = true;
 }
예제 #26
0
 internal ControlConnection(ICluster cluster, Metadata metadata)
 {
     Metadata = metadata;
     _reconnectionSchedule = _reconnectionPolicy.NewSchedule();
     _reconnectionTimer = new Timer(_ => Refresh(true), null, Timeout.Infinite, Timeout.Infinite);
     _config = cluster.Configuration;
 }