示例#1
0
        /// <summary>
        ///  Returns the hosts to use for a new query. <p> The returned plan will first
        ///  return replicas (whose <c>HostDistance</c> for the child policy is
        ///  <c>Local</c>) for the query if it can determine them (i.e. mainly if
        ///  <c>query.getRoutingKey()</c> is not <c>null</c>). Following what
        ///  it will return the plan of the child policy.</p>
        /// </summary>
        /// <param name="query"> the query for which to build the plan. </param>
        ///
        /// <returns>the new query plan.</returns>
        public IEnumerable <Host> NewQueryPlan(IStatement query)
        {
            RoutingKey routingKey = query == null ? null : query.RoutingKey;

            if (routingKey == null)
            {
                foreach (var iter in _childPolicy.NewQueryPlan(null))
                {
                    yield return(iter);
                }
                yield break;
            }

            ICollection <IPEndPoint> replicas = _cluster.GetReplicas(routingKey.RawRoutingKey);

            if (replicas.Count == 0)
            {
                foreach (var iter in _childPolicy.NewQueryPlan(query))
                {
                    yield return(iter);
                }
                yield break;
            }

            IEnumerator <IPEndPoint> iterator = replicas.GetEnumerator();

            while (iterator.MoveNext())
            {
                var host = _cluster.GetHost(iterator.Current);
                if (host != null && _childPolicy.Distance(host) == HostDistance.Local)
                {
                    yield return(host);
                }
            }

            IEnumerable <Host> childIterator = _childPolicy.NewQueryPlan(query);
            var remoteChildren = new HashSet <Host>();

            foreach (var host in childIterator)
            {
                if (replicas.Contains(host.Address))
                {
                    continue;
                }
                if (_childPolicy.Distance(host) != HostDistance.Local)
                {
                    remoteChildren.Add(host);
                }
                else
                {
                    yield return(host);
                }
            }

            foreach (var host in remoteChildren)
            {
                yield return(host);
            }
        }
        /// <summary>
        ///  Returns the hosts to use for a new query. <p> The returned plan will first
        ///  return replicas (whose <code>HostDistance</code> for the child policy is
        ///  <code>Local</code>) for the query if it can determine them (i.e. mainly if
        ///  <code>query.getRoutingKey()</code> is not <code>null</code>). Following what
        ///  it will return the plan of the child policy.</p>
        /// </summary>
        /// <param name="query"> the query for which to build the plan. </param>
        ///
        /// <returns>the new query plan.</returns>
        public IEnumerable <Host> NewQueryPlan(Query query)
        {
            var routingKey = query == null ? null : query.RoutingKey;

            if (routingKey == null)
            {
                foreach (var iter in _childPolicy.NewQueryPlan(null))
                {
                    yield return(iter);
                }
                yield break;
            }

            var replicas = _cluster.Metadata.GetReplicas(routingKey.RawRoutingKey);

            if (replicas.Count == 0)
            {
                foreach (var iter in _childPolicy.NewQueryPlan(query))
                {
                    yield return(iter);
                }
                yield break;
            }

            var iterator = replicas.GetEnumerator();

            while (iterator.MoveNext())
            {
                var host = _cluster.Metadata.GetHost(iterator.Current);
                if (host != null && host.IsConsiderablyUp && _childPolicy.Distance(host) == HostDistance.Local)
                {
                    yield return(host);
                }
            }

            var childIterator  = _childPolicy.NewQueryPlan(query);
            var remoteChildren = new HashSet <Host>();

            foreach (var host in childIterator)
            {
                if (!replicas.Contains(host.Address))
                {
                    if (_childPolicy.Distance(host) != HostDistance.Local)
                    {
                        remoteChildren.Add(host);
                    }
                    else
                    {
                        yield return(host);
                    }
                }
            }

            foreach (var host in remoteChildren)
            {
                yield return(host);
            }
        }
示例#3
0
        /// <summary>
        ///  Returns the hosts to use for a new query. <p> The returned plan will first
        ///  return replicas (whose <c>HostDistance</c> for the child policy is
        ///  <c>Local</c>) for the query if it can determine them (i.e. mainly if
        ///  <c>IStatement.RoutingKey</c> is not <c>null</c>). Following what
        ///  it will return the plan of the child policy.</p>
        /// </summary>
        /// <param name="loggedKeyspace">Keyspace on which the query is going to be executed</param>
        /// <param name="query"> the query for which to build the plan. </param>
        /// <returns>the new query plan.</returns>
        public IEnumerable <Host> NewQueryPlan(string loggedKeyspace, IStatement query)
        {
            var routingKey = query == null ? null : query.RoutingKey;
            IEnumerable <Host> childIterator;

            if (routingKey == null)
            {
                childIterator = _childPolicy.NewQueryPlan(loggedKeyspace, query);
                foreach (var h in childIterator)
                {
                    yield return(h);
                }
                yield break;
            }
            var keyspace = loggedKeyspace;
            // Story: Keyspace property has been added at Statement abstract class level and not at interface level
            // to avoid introducing a breaking change
            var statement = query as Statement;

            if (statement != null && statement.Keyspace != null)
            {
                keyspace = statement.Keyspace;
            }

            var replicas = _cluster.GetReplicas(keyspace, routingKey.RawRoutingKey);

            var localReplicaSet  = new HashSet <Host>();
            var localReplicaList = new List <Host>(replicas.Count);

            // We can't do it lazily as we need to balance the load between local replicas
            foreach (var localReplica in replicas.Where(h => _childPolicy.Distance(h) == HostDistance.Local))
            {
                localReplicaSet.Add(localReplica);
                localReplicaList.Add(localReplica);
            }
            // Return the local replicas first
            if (localReplicaList.Count > 0)
            {
                // Use a pseudo random start index
                var startIndex = _prng.Value.Next();
                for (var i = 0; i < localReplicaList.Count; i++)
                {
                    yield return(localReplicaList[(startIndex + i) % localReplicaList.Count]);
                }
            }

            // Then, return the rest of child policy hosts
            childIterator = _childPolicy.NewQueryPlan(loggedKeyspace, query);
            foreach (var h in childIterator)
            {
                if (localReplicaSet.Contains(h))
                {
                    continue;
                }
                yield return(h);
            }
        }
        /// <summary>
        /// Returns the hosts to used for a query.
        /// </summary>
        public IEnumerable <Host> NewQueryPlan(string keyspace, IStatement statement)
        {
            var targettedStatement = statement as TargettedSimpleStatement;

            if (targettedStatement != null && targettedStatement.PreferredHost != null)
            {
                _lastPreferredHost = targettedStatement.PreferredHost;
                return(YieldPreferred(keyspace, targettedStatement));
            }
            return(_childPolicy.NewQueryPlan(keyspace, statement));
        }
示例#5
0
        public IEnumerable <Host> NewQueryPlan(IStatement query)
        {
            IReconnectionSchedule schedule = _reconnectionPolicy.NewSchedule();

            while (true)
            {
                IEnumerable <Host> childQueryPlan = _loadBalancingPolicy.NewQueryPlan(query);
                foreach (Host host in childQueryPlan)
                {
                    yield return(host);
                }

                if (ReconnectionEvent != null)
                {
                    var ea = new RetryLoadBalancingPolicyEventArgs(schedule.NextDelayMs());
                    ReconnectionEvent(this, ea);
                    if (ea.Cancel)
                    {
                        break;
                    }
                }
                else
                {
                    Thread.Sleep((int)schedule.NextDelayMs());
                }
            }
        }
示例#6
0
        /// <summary>
        /// Gets a query plan as determined by the load-balancing policy.
        /// In the special case when a Host is provided at Statement level, it will return a query plan with a single
        /// host.
        /// </summary>
        private static IEnumerable <Host> GetQueryPlan(ISession session, IStatement statement, ILoadBalancingPolicy lbp)
        {
            // Single host iteration
            var host = (statement as Statement)?.Host;

            return(host == null
                ? lbp.NewQueryPlan(session.Keyspace, statement)
                : Enumerable.Repeat(host, 1));
        }
示例#7
0
        public IEnumerable <Host> NewQueryPlan(string keyspace, IStatement query)
        {
            IEnumerable <Host> result = null;
            var boundStatement        = query as BoundStatement;

            if (boundStatement != null)
            {
                result = NewQueryPlanImpl(keyspace, boundStatement);
            }
            else
            {
                var batchStatement = query as BatchStatement;
                if (batchStatement != null)
                {
                    result = NewQueryPlanImpl(keyspace, batchStatement);
                }
            }
            if (result == null)
            {
                result = _childPolicy.NewQueryPlan(keyspace, query);
            }
            return(result);
        }
示例#8
0
 public IEnumerable <Host> NewQueryPlan(string keyspace, IStatement query)
 {
     return(!_useRoundRobin ? _hosts : _childPolicy.NewQueryPlan(keyspace, query));
 }
示例#9
0
        /// <summary>
        ///  Returns the hosts to use for a new query. <p> The returned plan will first
        ///  return replicas (whose <c>HostDistance</c> for the child policy is
        ///  <c>Local</c>) for the query if it can determine them (i.e. mainly if
        ///  <c>IStatement.RoutingKey</c> is not <c>null</c>). Following what
        ///  it will return the plan of the child policy.</p>
        /// </summary>
        /// <param name="keyspace">Keyspace on which the query is going to be executed</param>
        /// <param name="query"> the query for which to build the plan. </param>
        /// <returns>the new query plan.</returns>
        public IEnumerable <Host> NewQueryPlan(string keyspace, IStatement query)
        {
            var routingKey = query == null ? null : query.RoutingKey;
            IEnumerable <Host> childIterator;

            if (routingKey == null)
            {
                childIterator = _childPolicy.NewQueryPlan(keyspace, query);
                foreach (var h in childIterator)
                {
                    yield return(h);
                }
                yield break;
            }
            var replicas = _cluster.GetReplicas(keyspace, routingKey.RawRoutingKey);
            //We need to have split into local and remote replicas
            //We need actual lists (not lazy) as we need to round-robin through them
            var localReplicas  = new List <Host>();
            var remoteReplicas = new List <Host>();

            foreach (var h in replicas)
            {
                var distance = _childPolicy.Distance(h);
                if (distance == HostDistance.Local)
                {
                    localReplicas.Add(h);
                }
                else if (distance == HostDistance.Remote)
                {
                    remoteReplicas.Add(h);
                }
            }
            //Return the local replicas first
            if (localReplicas.Count > 0)
            {
                //Round robin through the local replicas
                var roundRobinIndex = Interlocked.Increment(ref _index);
                //Overflow protection
                if (roundRobinIndex > int.MaxValue - 10000)
                {
                    Interlocked.Exchange(ref _index, 0);
                }
                for (var i = 0; i < localReplicas.Count; i++)
                {
                    yield return(localReplicas[(roundRobinIndex + i) % localReplicas.Count]);
                }
            }

            //Then, return the child policy hosts
            childIterator = _childPolicy.NewQueryPlan(keyspace, query);
            foreach (var h in childIterator)
            {
                //It is yielded with the rest of replicas
                if (replicas.Contains(h))
                {
                    continue;
                }
                yield return(h);
            }

            //Then, the remote replicas
            foreach (var h in remoteReplicas)
            {
                yield return(h);
            }
        }
示例#10
0
            public IEnumerable <Host> NewQueryPlan(string keyspace, IStatement query)
            {
                var hosts = _childPolicy.NewQueryPlan(keyspace, query);

                return(hosts.Where(h => _list.Contains(TestHelper.GetLastAddressByte(h))));
            }
示例#11
0
            public IEnumerable <Host> NewQueryPlan(string keyspace, IStatement query)
            {
                var plan = _parent.NewQueryPlan(keyspace, query);

                return(plan.Where(h => !_disallowed.Contains(h.Address)));
            }
示例#12
0
 public IEnumerable <Host> NewQueryPlan(string keyspace, IStatement query)
 {
     return(_childPolicy.NewQueryPlan(keyspace, query));
 }