Example #1
0
        /// <summary>
        /// Schedules the next delayed execution
        /// </summary>
        private void ScheduleNext()
        {
            if (Statement == null || !(Statement.IsIdempotent ?? _session.Cluster.Configuration.QueryOptions.GetDefaultIdempotence()))
            {
                //its not idempotent, we should not schedule an speculative execution
                return;
            }
            if (_executionPlan == null)
            {
                _executionPlan = Policies.SpeculativeExecutionPolicy.NewPlan(_session.Keyspace, Statement);
            }
            var delay = _executionPlan.NextExecution(_host);

            if (delay <= 0)
            {
                return;
            }
            //There is one live timer at a time.
            _nextExecutionTimeout = _session.Cluster.Configuration.Timer.NewTimeout(_ =>
            {
                if (HasCompleted())
                {
                    return;
                }
                Logger.Info("Starting new speculative execution after {0}, last used host {1}", delay, _host.Address);
                StartNewExecution();
            }, null, delay);
        }
Example #2
0
        public void ConsiderResizingPool(int inFlight)
        {
            if (inFlight < _maxInflightThreshold)
            {
                // The requests in-flight are normal
                return;
            }
            if (_expectedConnectionLength >= _maxConnectionLength)
            {
                // We can not add more connections
                return;
            }
            if (_connections.Count < _expectedConnectionLength)
            {
                // The pool is still trying to acquire the correct size
                return;
            }
            var canResize = Interlocked.Exchange(ref _poolResizing, 1) == 0;

            if (!canResize)
            {
                // There is already another thread resizing the pool
                return;
            }
            if (IsClosing)
            {
                return;
            }
            _expectedConnectionLength++;
            Logger.Info("Increasing pool #{0} size to {1}, as in-flight requests are above threshold ({2})",
                        GetHashCode(), _expectedConnectionLength, _maxInflightThreshold);
            StartCreatingConnection(null);
            _resizingEndTimeout = _timer.NewTimeout(_ => Interlocked.Exchange(ref _poolResizing, 0), null,
                                                    BetweenResizeDelay);
        }
Example #3
0
        /// <summary>
        /// Schedules the next delayed execution
        /// </summary>
        private void ScheduleNext(Host currentHost)
        {
            if (Statement == null || Statement.IsIdempotent == false)
            {
                //its not idempotent, we should not schedule an speculative execution
                return;
            }
            if (_executionPlan == null)
            {
                _executionPlan = Policies.SpeculativeExecutionPolicy.NewPlan(_session.Keyspace, Statement);
            }
            var delay = _executionPlan.NextExecution(currentHost);

            if (delay <= 0)
            {
                return;
            }
            //There is one live timer at a time.
            _nextExecutionTimeout = _session.Cluster.Configuration.Timer.NewTimeout(_ =>
            {
                // Start the speculative execution outside the IO thread
                Task.Run(() =>
                {
                    if (HasCompleted())
                    {
                        return;
                    }
                    RequestHandler.Logger.Info("Starting new speculative execution after {0}, last used host {1}", delay, currentHost.Address);
                    StartNewExecution();
                });
            }, null, delay);
        }
Example #4
0
        /// <summary>
        /// Cancels the previous and set the next reconnection timeout, as an atomic operation.
        /// </summary>
        private void SetReconnectionTimeout(HashedWheelTimer.ITimeout nextTimeout)
        {
            var timeout = Interlocked.Exchange(ref _timeout, nextTimeout);

            if (timeout != null)
            {
                timeout.Cancel();
            }
        }
        private void OnHostUp(Host host)
        {
            var timeout = _timeout;

            if (timeout != null)
            {
                timeout.Cancel();
            }
            _timeout = null;
            //The host is back up, we can start creating the pool (if applies)
            MaybeCreateCorePool();
        }
Example #6
0
        private void CancelNewConnectionTimeout(HashedWheelTimer.ITimeout newTimeout = null)
        {
            var previousTimeout = Interlocked.Exchange(ref _newConnectionTimeout, newTimeout);

            if (previousTimeout != null)
            {
                // Clear previous reconnection attempt timeout
                previousTimeout.Cancel();
            }
            if (newTimeout != null && IsClosing)
            {
                // It could have been the case the it was set after it was set as closed.
                Interlocked.Exchange(ref _newConnectionTimeout, null);
            }
        }
Example #7
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);
     }
 }
        private void OnHostDown(Host h, long delay)
        {
            if (Interlocked.CompareExchange(ref _hostDownFlag, 1, 0) != 0)
            {
                //A reconnection attempt is being scheduled concurrently
                return;
            }
            var currentTimeout = _timeout;

            //De-schedule the current reconnection attempt
            if (currentTimeout != null)
            {
                currentTimeout.Cancel();
            }
            //Schedule next reconnection attempt (without using the timer thread)
            _timeout = _timer.NewTimeout(() => Task.Factory.StartNew(AttemptReconnection), delay);
            //Dispose all current connections
            foreach (var c in _connections)
            {
                //Connection class allows multiple calls to Dispose
                c.Dispose();
            }
            Interlocked.Exchange(ref _hostDownFlag, 0);
        }
Example #9
0
 /// <summary>
 /// Sets the read timeout associated with the request
 /// </summary>
 public void SetTimeout(HashedWheelTimer.ITimeout value)
 {
     _timeout = value;
 }
 private void OnHostUp(Host host)
 {
     var timeout = _timeout;
     if (timeout != null)
     {
         timeout.Cancel();
     }
     _timeout = null;
     //The host is back up, we can start creating the pool (if applies)
     MaybeCreateCorePool();
 }
 private void OnHostDown(Host h, long delay)
 {
     if (Interlocked.CompareExchange(ref _hostDownFlag, 1, 0) != 0)
     {
         //A reconnection attempt is being scheduled concurrently
         return;
     }
     var currentTimeout = _timeout;
     //De-schedule the current reconnection attempt
     if (currentTimeout != null)
     {
         currentTimeout.Cancel();
     }
     //Schedule next reconnection attempt (without using the timer thread)
     _timeout = _timer.NewTimeout(() => Task.Factory.StartNew(AttemptReconnection), delay);
     //Dispose all current connections
     foreach (var c in _connections)
     {
         //Connection class allows multiple calls to Dispose
         c.Dispose();
     }
     Interlocked.Exchange(ref _hostDownFlag, 0);
 }