/// <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); } }
/// <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)); }
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()); } } }
/// <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)); }
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); }
public IEnumerable <Host> NewQueryPlan(string keyspace, IStatement query) { return(!_useRoundRobin ? _hosts : _childPolicy.NewQueryPlan(keyspace, query)); }
/// <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); } }
public IEnumerable <Host> NewQueryPlan(string keyspace, IStatement query) { var hosts = _childPolicy.NewQueryPlan(keyspace, query); return(hosts.Where(h => _list.Contains(TestHelper.GetLastAddressByte(h)))); }
public IEnumerable <Host> NewQueryPlan(string keyspace, IStatement query) { var plan = _parent.NewQueryPlan(keyspace, query); return(plan.Where(h => !_disallowed.Contains(h.Address))); }
public IEnumerable <Host> NewQueryPlan(string keyspace, IStatement query) { return(_childPolicy.NewQueryPlan(keyspace, query)); }