Exemplo n.º 1
0
        private void RefreshNodeListAndTokenMap()
        {
            _logger.Info("Refreshing NodeList and TokenMap..");
            // Make sure we're up to date on nodes and tokens
            var    tokenMap    = new Dictionary <IPAddress, DictSet <string> >();
            string partitioner = null;

            var       foundHosts = new List <IPAddress>();
            var       dcs        = new List <string>();
            var       racks      = new List <string>();
            var       allTokens  = new List <DictSet <string> >();
            IPAddress queriedHost;

            using (var rowset = _session.Query(SelectPeers, ConsistencyLevel.Quorum))
            {
                queriedHost = rowset.Info.QueriedHost;
                foreach (var row in rowset.GetRows())
                {
                    IPAddress hstip = null;
                    if (!row.IsNull("rpc_address"))
                    {
                        hstip = row.GetValue <IPEndPoint>("rpc_address").Address;
                    }
                    if (hstip == null)
                    {
                        if (!row.IsNull("peer"))
                        {
                            hstip = row.GetValue <IPEndPoint>("peer").Address;
                        }
                        _logger.Error("No rpc_address found for host in peers system table. ");
                    }
                    else if (hstip.Equals(bindAllAddress))
                    {
                        if (!row.IsNull("peer"))
                        {
                            hstip = row.GetValue <IPEndPoint>("peer").Address;
                        }
                    }

                    if (hstip != null)
                    {
                        foundHosts.Add(hstip);
                        dcs.Add(row.GetValue <string>("data_center"));
                        racks.Add(row.GetValue <string>("rack"));
                        var col = row.GetValue <IEnumerable <string> >("tokens");
                        if (col == null)
                        {
                            allTokens.Add(new DictSet <string>());
                        }
                        else
                        {
                            allTokens.Add(new DictSet <string>(col));
                        }
                    }
                }
            }

            var localhost = _cluster.Metadata.GetHost(queriedHost);
            var iterLiof  = new List <Host>()
            {
                localhost
            }.GetEnumerator();

            iterLiof.MoveNext();
            List <IPAddress> tr = new List <IPAddress>();
            Dictionary <IPAddress, List <Exception> > exx = new Dictionary <IPAddress, List <Exception> >();
            int streamId;
            var cn = _session.Connect(null, iterLiof, tr, exx, out streamId);

            using (var outp = cn.Query(streamId, SelectLocal, ConsistencyLevel.Default, false))
            {
                if (outp is OutputRows)
                {
                    var rowset = new RowSet((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())
                    {
                        var clusterName = localRow.GetValue <string>("cluster_name");
                        if (clusterName != null)
                        {
                            _cluster.Metadata.ClusterName = clusterName;
                        }



                        // In theory host can't be null. However there is no point in risking a NPE in case we
                        // have a race between a node removal and this.
                        if (localhost != null)
                        {
                            localhost.SetLocationInfo(localRow.GetValue <string>("data_center"), localRow.GetValue <string>("rack"));

                            partitioner = localRow.GetValue <string>("partitioner");
                            var tokens = localRow.GetValue <IList <string> >("tokens");
                            if (partitioner != null && tokens.Count > 0)
                            {
                                if (!tokenMap.ContainsKey(localhost.Address))
                                {
                                    tokenMap.Add(localhost.Address, new DictSet <string>());
                                }
                                tokenMap[localhost.Address].AddRange(tokens);
                            }
                        }

                        break; //fetch only one row
                    }
                }
            }

            for (int i = 0; i < foundHosts.Count; i++)
            {
                var host = _cluster.Metadata.GetHost(foundHosts[i]);
                if (host == null)
                {
                    // We don't know that node, add it.
                    host = _cluster.Metadata.AddHost(foundHosts[i]);
                }
                host.SetLocationInfo(dcs[i], racks[i]);

                if (partitioner != null && !allTokens[i].IsEmpty)
                {
                    tokenMap.Add(host.Address, allTokens[i]);
                }
            }

            // Removes all those that seems to have been removed (since we lost the control connection)
            var foundHostsSet = new DictSet <IPAddress>(foundHosts);

            foreach (var host in _cluster.Metadata.AllReplicas())
            {
                if (!host.Equals(queriedHost) && !foundHostsSet.Contains(host))
                {
                    _cluster.Metadata.RemoveHost(host);
                }
            }

            if (partitioner != null)
            {
                _cluster.Metadata.RebuildTokenMap(partitioner, tokenMap);
            }

            _logger.Info("NodeList and TokenMap have been successfully refreshed!");
        }