Example #1
0
        public static TokenMap Build(String partitioner, Dictionary <IPAddress, DictSet <string> > allTokens)
        {
            TokenFactory factory = TokenFactory.GetFactory(partitioner);

            if (factory == null)
            {
                return(null);
            }

            Dictionary <IToken, DictSet <IPAddress> > tokenToCassandraClusterHosts = new Dictionary <IToken, DictSet <IPAddress> >();
            DictSet <IToken> allSorted = new DictSet <IToken>();

            foreach (var entry in allTokens)
            {
                var cassandraClusterHost = entry.Key;
                foreach (string tokenStr in entry.Value)
                {
                    try
                    {
                        IToken t = factory.Parse(tokenStr);
                        allSorted.Add(t);
                        if (!tokenToCassandraClusterHosts.ContainsKey(t))
                        {
                            tokenToCassandraClusterHosts.Add(t, new DictSet <IPAddress>());
                        }
                        tokenToCassandraClusterHosts[t].Add(cassandraClusterHost);
                    }
                    catch (ArgumentException e)
                    {
                        // If we failed parsing that token, skip it
                    }
                }
            }
            return(new TokenMap(factory, tokenToCassandraClusterHosts, new List <IToken>(allSorted)));
        }
        /// <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 DictSet <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);
            }
        }
        internal bool WaitForSchemaAgreement(IPAddress forHost = null)
        {
            var  start   = DateTimeOffset.Now;
            long elapsed = 0;

            while (elapsed < MaxSchemaAgreementWaitMs)
            {
                var versions = new DictSet <Guid>();


                IPAddress queriedHost;

                if (forHost == null)
                {
                    using (var rowset = _session.Query(SelectSchemaPeers, ConsistencyLevel.Default))
                    {
                        queriedHost = rowset.QueriedHost;
                        foreach (var row in rowset.GetRows())
                        {
                            if (row.IsNull("peer") || row.IsNull("schema_version"))
                            {
                                continue;
                            }

                            Host peer = _cluster.Metadata.GetHost(row.GetValue <IPEndPoint>("peer").Address);
                            if (peer != null && peer.IsConsiderablyUp)
                            {
                                versions.Add(row.GetValue <Guid>("schema_version"));
                            }
                        }
                    }
                }
                else
                {
                    queriedHost = forHost;
                    var localhost = _cluster.Metadata.GetHost(queriedHost);
                    var iterLiof  = new List <Host>()
                    {
                        localhost
                    }.GetEnumerator();
                    iterLiof.MoveNext();
                    List <IPAddress> tr = new List <IPAddress>();
                    Dictionary <IPAddress, Exception> exx = new Dictionary <IPAddress, Exception>();
                    var cn = _session.Connect(null, iterLiof, tr, exx);

                    using (var outp = cn.Query(SelectSchemaPeers, ConsistencyLevel.Default, false))
                    {
                        if (outp is OutputRows)
                        {
                            var rowset = new CqlRowSet((outp as OutputRows), null, false);
                            foreach (var row in rowset.GetRows())
                            {
                                if (row.IsNull("peer") || row.IsNull("schema_version"))
                                {
                                    continue;
                                }

                                Host peer = _cluster.Metadata.GetHost(row.GetValue <IPEndPoint>("peer").Address);
                                if (peer != null && peer.IsConsiderablyUp)
                                {
                                    versions.Add(row.GetValue <Guid>("schema_version"));
                                }
                            }
                        }
                    }
                }

                {
                    var localhost = _cluster.Metadata.GetHost(queriedHost);
                    var iterLiof  = new List <Host>()
                    {
                        localhost
                    }.GetEnumerator();
                    iterLiof.MoveNext();
                    List <IPAddress> tr = new List <IPAddress>();
                    Dictionary <IPAddress, Exception> exx = new Dictionary <IPAddress, Exception>();
                    var cn = _session.Connect(null, iterLiof, tr, exx);

                    using (var outp = cn.Query(SelectSchemaLocal, ConsistencyLevel.Default, false))
                    {
                        if (outp is OutputRows)
                        {
                            var rowset = new CqlRowSet((outp as OutputRows), null, false);
                            // Update cluster name, DC and rack for the one node we are connected to
                            foreach (var localRow in rowset.GetRows())
                            {
                                if (!localRow.IsNull("schema_version"))
                                {
                                    versions.Add(localRow.GetValue <Guid>("schema_version"));
                                    break;
                                }
                            }
                        }
                    }
                }


                if (versions.Count <= 1)
                {
                    return(true);
                }

                // let's not flood the node too much
                Thread.Sleep(200);
                elapsed = (long)(DateTimeOffset.Now - start).TotalMilliseconds;
            }

            return(false);
        }