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); }
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.QueriedHost; foreach (var row in rowset.GetRows()) { var 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, Exception> exx = new Dictionary <IPAddress, Exception>(); var cn = _session.Connect(null, iterLiof, tr, exx); using (var outp = cn.Query(SelectLocal, 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()) { 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!"); }