Exemplo n.º 1
0
        public static TokenMap Build(string partitioner, ICollection <Host> hosts, ICollection <KeyspaceMetadata> keyspaces)
        {
            var sw = new Stopwatch();

            sw.Start();
            var factory = TokenFactory.GetFactory(partitioner);

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

            var primaryReplicas = new Dictionary <IToken, Host>();
            var allSorted       = new SortedSet <IToken>();
            var datacenters     = new Dictionary <string, DatacenterInfo>();

            foreach (var host in hosts)
            {
                if (host.Datacenter != null)
                {
                    if (!datacenters.TryGetValue(host.Datacenter, out var dc))
                    {
                        datacenters[host.Datacenter] = dc = new DatacenterInfo();
                    }
                    dc.HostLength++;
                    dc.AddRack(host.Rack);
                }
                foreach (var tokenStr in host.Tokens)
                {
                    try
                    {
                        var token = factory.Parse(tokenStr);
                        allSorted.Add(token);
                        primaryReplicas[token] = host;
                    }
                    catch (Exception ex)
                    {
                        TokenMap.Logger.Error($"Token {tokenStr} could not be parsed using {partitioner} partitioner implementation. Exception: {ex}");
                    }
                }
            }
            var ring          = new List <IToken>(allSorted);
            var tokenToHosts  = new Dictionary <string, IReadOnlyDictionary <IToken, ISet <Host> > >(keyspaces.Count);
            var ksTokensCache = new Dictionary <IReplicationStrategy, IReadOnlyDictionary <IToken, ISet <Host> > >();
            //Only consider nodes that have tokens
            var numberOfHostsWithTokens = hosts.Count(h => h.Tokens.Any());

            foreach (var ks in keyspaces)
            {
                TokenMap.UpdateKeyspace(ks, tokenToHosts, ring, primaryReplicas, ksTokensCache, datacenters, numberOfHostsWithTokens);
            }

            sw.Stop();
            TokenMap.Logger.Info(
                "Finished building TokenMap for {0} keyspaces and {1} hosts. It took {2:0} milliseconds.",
                keyspaces.Count,
                hosts.Count,
                sw.Elapsed.TotalMilliseconds);
            return(new TokenMap(factory, tokenToHosts, ring, primaryReplicas, ksTokensCache, datacenters, numberOfHostsWithTokens));
        }
Exemplo n.º 2
0
        internal async Task <KeyspaceMetadata> UpdateTokenMapForKeyspace(string name)
        {
            var keyspaceMetadata = await _schemaParser.GetKeyspaceAsync(name).ConfigureAwait(false);

            var dropped = false;
            var updated = false;

            if (_tokenMap == null)
            {
                await RebuildTokenMapAsync(false, false).ConfigureAwait(false);
            }

            if (keyspaceMetadata == null)
            {
                Metadata.Logger.Verbose("Removing keyspace metadata: " + name);
                dropped = _keyspaces.TryRemove(name, out _);
                _tokenMap?.RemoveKeyspace(name);
            }
            else
            {
                Metadata.Logger.Verbose("Updating keyspace metadata: " + name);
                _keyspaces.AddOrUpdate(keyspaceMetadata.Name, keyspaceMetadata, (k, v) =>
                {
                    updated = true;
                    return(keyspaceMetadata);
                });
                Metadata.Logger.Info("Rebuilding token map for keyspace {0}", keyspaceMetadata.Name);
                if (Partitioner == null)
                {
                    throw new DriverInternalError("Partitioner can not be null");
                }

                _tokenMap.UpdateKeyspace(keyspaceMetadata);
            }

            if (Configuration.MetadataSyncOptions.MetadataSyncEnabled)
            {
                if (dropped)
                {
                    FireSchemaChangedEvent(SchemaChangedEventArgs.Kind.Dropped, name, null, this);
                }
                else if (updated)
                {
                    FireSchemaChangedEvent(SchemaChangedEventArgs.Kind.Updated, name, null, this);
                }
                else
                {
                    FireSchemaChangedEvent(SchemaChangedEventArgs.Kind.Created, name, null, this);
                }
            }

            return(keyspaceMetadata);
        }
Exemplo n.º 3
0
        internal async Task <KeyspaceMetadata> UpdateTokenMapForKeyspace(string name)
        {
            var currentCounter         = Interlocked.Read(ref _counterRebuild);
            var currentKeyspaceCounter = _keyspacesUpdateCounters.GetOrAdd(name, s => 0);

            // running this statement synchronously inside the exclusive scheduler deadlocks
            var keyspaceMetadata = await _schemaParser.GetKeyspace(name).ConfigureAwait(false);

            var task = _tokenMapTaskFactory.StartNew(
                () =>
            {
                if (AnotherRebuildCompleted(currentCounter))
                {
                    return(true);
                }

                if (!UpdateKeyspaceNecessary(name, currentKeyspaceCounter))
                {
                    return(true);
                }

                if (_tokenMap == null)
                {
                    return(false);
                }

                Metadata.Logger.Verbose("Updating keyspace metadata: " + name);
                if (keyspaceMetadata == null)
                {
                    return((bool?)null);
                }

                _keyspaces.AddOrUpdate(keyspaceMetadata.Name, keyspaceMetadata, (k, v) => keyspaceMetadata);
                Metadata.Logger.Info("Rebuilding token map for keyspace {0}", keyspaceMetadata.Name);
                if (Partitioner == null)
                {
                    throw new DriverInternalError("Partitioner can not be null");
                }

                _tokenMap.UpdateKeyspace(keyspaceMetadata);
                return(true);
            });

            var existsTokenMap = await task.ConfigureAwait(false);

            if (existsTokenMap.HasValue && !existsTokenMap.Value)
            {
                await RefreshKeyspaces().ConfigureAwait(false);
            }

            return(keyspaceMetadata);
        }
Exemplo n.º 4
0
        public void UpdateKeyspace(KeyspaceMetadata ks)
        {
            var sw = new Stopwatch();

            sw.Start();

            TokenMap.UpdateKeyspace(
                ks, _tokenToHostsByKeyspace, _ring, _primaryReplicas, _keyspaceTokensCache, _datacenters, _numberOfHostsWithTokens);

            sw.Stop();
            TokenMap.Logger.Info(
                "Finished updating TokenMap for the '{0}' keyspace. It took {1:0} milliseconds.",
                ks.Name,
                sw.Elapsed.TotalMilliseconds);
        }