예제 #1
0
 public FindTabletResult(RemoteTablet tablet, int index)
 {
     Tablet = tablet;
     Index  = index;
     NonCoveredRangeStart = null;
     NonCoveredRangeEnd   = null;
 }
예제 #2
0
    /// <summary>
    /// Helper method to easily kill a tablet server that serves the given table's
    /// only tablet's leader. The currently running test case will be failed if
    /// there's more than one tablet, if the tablet has no leader after some retries,
    /// or if the tablet server was already killed.
    /// </summary>
    /// <param name="tablet">A RemoteTablet which will get its leader killed.</param>
    /// <returns>
    /// The host and port of the tablet server which hosted the tablet's leader replica.
    /// </returns>
    public async Task <HostAndPort> KillTabletLeaderAsync(RemoteTablet tablet)
    {
        var hostPort = await FindLeaderTabletServerAsync(tablet);

        await _miniCluster.KillTabletServerAsync(hostPort);

        return(hostPort);
    }
예제 #3
0
    public static TableLocationEntry NewCoveredRange(RemoteTablet tablet, long expiration)
    {
        var partition = tablet.Partition;
        var lowerBoundPartitionKey = partition.PartitionKeyStart;
        var upperBoundPartitionKey = partition.PartitionKeyEnd;

        return(new TableLocationEntry(
                   tablet, lowerBoundPartitionKey, upperBoundPartitionKey, expiration));
    }
예제 #4
0
    private static FindTabletResult HandleMissingTablet(
        List <RemoteTablet> tablets, int nextIndex, RemoteTablet tablet)
    {
        var nonCoveredRangeStart = tablet.Partition.PartitionKeyEnd;

        var nonCoveredRangeEnd = tablets.Count == nextIndex
            ? Array.Empty <byte>()
            : tablets[nextIndex].Partition.PartitionKeyStart;

        return(new FindTabletResult(nonCoveredRangeStart, nonCoveredRangeEnd));
    }
예제 #5
0
 /// <summary>
 /// Create a new key range [primaryKeyStart, primaryKeyEnd).
 /// </summary>
 /// <param name="tablet">The tablet which the key range belongs to.</param>
 /// <param name="primaryKeyStart">
 /// The encoded primary key where to start in the key range (inclusive).
 /// </param>
 /// <param name="primaryKeyEnd">
 /// The encoded primary key where to stop in the key range (exclusive).
 /// </param>
 /// <param name="dataSizeBytes">The estimated data size of the key range.</param>
 public KeyRange(
     RemoteTablet tablet,
     ReadOnlyMemory <byte> primaryKeyStart,
     ReadOnlyMemory <byte> primaryKeyEnd,
     long dataSizeBytes)
 {
     Tablet          = tablet;
     PrimaryKeyStart = primaryKeyStart;
     PrimaryKeyEnd   = primaryKeyEnd;
     DataSizeBytes   = dataSizeBytes;
 }
예제 #6
0
    /// <summary>
    /// Finds the RPC port of the given tablet's leader tserver.
    /// </summary>
    /// <param name="tablet">The remote tablet.</param>
    public async ValueTask <HostAndPort> FindLeaderTabletServerAsync(RemoteTablet tablet)
    {
        var leader = tablet.GetLeaderServerInfo();

        while (leader == null)
        {
            await Task.Delay(100);

            var tablets = await _client.GetTableLocationsAsync(
                tablet.TableId, tablet.Partition.PartitionKeyStart, 1);

            var foundTablet = Assert.Single(tablets);
            leader = foundTablet.GetLeaderServerInfo();
        }

        return(leader.HostPort);
    }
예제 #7
0
 public void UpdateTablet(RemoteTablet tablet)
 {
     _lock.EnterWriteLock();
     try
     {
         if (_cache.Search(tablet.Partition.PartitionKeyStart, out var cacheEntry) &&
             cacheEntry.IsCoveredRange)
         {
             var newEntry = TableLocationEntry.NewCoveredRange(tablet, cacheEntry.Expiration);
             _cache.Insert(newEntry);
         }
     }
     finally
     {
         _lock.ExitWriteLock();
     }
 }
예제 #8
0
    public static async Task <List <RemoteTablet> > GetTabletsAsync(
        this IKuduConnectionFactory connectionFactory,
        string tableId, GetTableLocationsResponsePB locations)
    {
        // TODO: Need error handling here.
        var tsInfos         = locations.TsInfos;
        var internedServers = new List <ServerInfo>(tsInfos.Count);
        var results         = new List <RemoteTablet>(locations.TabletLocations.Count);

        foreach (var tsInfo in tsInfos)
        {
            var serverInfo = await GetServerInfoAsync(connectionFactory, tsInfo)
                             .ConfigureAwait(false);

            if (serverInfo is not null)
            {
                internedServers.Add(serverInfo);
            }
        }

        foreach (var tabletInfo in locations.TabletLocations)
        {
            var tabletId  = tabletInfo.TabletId.ToStringUtf8();
            var partition = ProtobufHelper.ToPartition(tabletInfo.Partition);

            var numReplicas = Math.Max(
                tabletInfo.DEPRECATEDReplicas.Count,
                tabletInfo.InternedReplicas.Count);

            var servers     = new List <ServerInfo>(numReplicas);
            var replicas    = new List <KuduReplica>(numReplicas);
            int leaderIndex = -1;

            // Handle interned replicas.
            foreach (var replicaPb in tabletInfo.InternedReplicas)
            {
                var tsInfoIdx  = (int)replicaPb.TsInfoIdx;
                var serverInfo = internedServers[tsInfoIdx];

                var replica = new KuduReplica(
                    serverInfo.HostPort,
                    (ReplicaRole)replicaPb.Role,
                    replicaPb.DimensionLabel);

                if (replica.Role == ReplicaRole.Leader)
                {
                    leaderIndex = servers.Count;
                }

                servers.Add(serverInfo);
                replicas.Add(replica);
            }

            // Handle "old-style" non-interned replicas.
            // It's used for backward compatibility.
            foreach (var replicaPb in tabletInfo.DEPRECATEDReplicas)
            {
                var serverInfo = await connectionFactory.GetServerInfoAsync(
                    replicaPb.TsInfo).ConfigureAwait(false);

                if (serverInfo != null)
                {
                    var replica = new KuduReplica(
                        serverInfo.HostPort,
                        (ReplicaRole)replicaPb.Role,
                        replicaPb.DimensionLabel);

                    if (replica.Role == ReplicaRole.Leader)
                    {
                        leaderIndex = servers.Count;
                    }

                    servers.Add(serverInfo);
                    replicas.Add(replica);
                }
            }

            var serverCache = new ServerInfoCache(servers, replicas, leaderIndex);

            var tablet = new RemoteTablet(
                tableId,
                tabletId,
                partition,
                serverCache);

            results.Add(tablet);
        }

        return(results);
    }