private async Task <PartitionAddressInformation> GetAddressesForRangeIdAsync( DocumentServiceRequest request, string collectionRid, string partitionKeyRangeId, bool forceRefresh) { FeedResource <Address> response = await this.GetServerAddressesViaGatewayAsync(request, collectionRid, new[] { partitionKeyRangeId }, forceRefresh); IEnumerable <Tuple <PartitionKeyRangeIdentity, PartitionAddressInformation> > addressInfos = response.Where(addressInfo => ProtocolFromString(addressInfo.Protocol) == this.protocol) .GroupBy(address => address.PartitionKeyRangeId, StringComparer.Ordinal) .Select(group => this.ToPartitionAddressAndRange(collectionRid, @group.ToList())); Tuple <PartitionKeyRangeIdentity, PartitionAddressInformation> result = addressInfos.SingleOrDefault( addressInfo => StringComparer.Ordinal.Equals(addressInfo.Item1.PartitionKeyRangeId, partitionKeyRangeId)); if (result == null) { string errorMessage = string.Format( CultureInfo.InvariantCulture, RMResources.PartitionKeyRangeNotFound, partitionKeyRangeId, collectionRid); throw new PartitionKeyRangeGoneException(errorMessage) { ResourceAddress = collectionRid }; } return(result.Item2); }
public async Task OpenAsync( string databaseName, ContainerProperties collection, IReadOnlyList <PartitionKeyRangeIdentity> partitionKeyRangeIdentities, CancellationToken cancellationToken) { List <Task <DocumentServiceResponse> > tasks = new List <Task <DocumentServiceResponse> >(); int batchSize = GatewayAddressCache.DefaultBatchSize; #if !(NETSTANDARD15 || NETSTANDARD16) #if NETSTANDARD20 // GetEntryAssembly returns null when loaded from native netstandard2.0 if (System.Reflection.Assembly.GetEntryAssembly() != null) { #endif int userSpecifiedBatchSize = 0; if (int.TryParse(System.Configuration.ConfigurationManager.AppSettings[GatewayAddressCache.AddressResolutionBatchSize], out userSpecifiedBatchSize)) { batchSize = userSpecifiedBatchSize; } #if NETSTANDARD20 } #endif #endif string collectionAltLink = string.Format(CultureInfo.InvariantCulture, "{0}/{1}/{2}/{3}", Paths.DatabasesPathSegment, Uri.EscapeUriString(databaseName), Paths.CollectionsPathSegment, Uri.EscapeUriString(collection.Id)); using (DocumentServiceRequest request = DocumentServiceRequest.CreateFromName( OperationType.Read, collectionAltLink, ResourceType.Collection, AuthorizationTokenType.PrimaryMasterKey)) { for (int i = 0; i < partitionKeyRangeIdentities.Count; i += batchSize) { tasks.Add(this.GetServerAddressesViaGatewayAsync( request, collection.ResourceId, partitionKeyRangeIdentities.Skip(i).Take(batchSize).Select(range => range.PartitionKeyRangeId), false)); } } foreach (DocumentServiceResponse response in await Task.WhenAll(tasks)) { using (response) { FeedResource <Address> addressFeed = response.GetResource <FeedResource <Address> >(); bool inNetworkRequest = this.IsInNetworkRequest(response); IEnumerable <Tuple <PartitionKeyRangeIdentity, PartitionAddressInformation> > addressInfos = addressFeed.Where(addressInfo => ProtocolFromString(addressInfo.Protocol) == this.protocol) .GroupBy(address => address.PartitionKeyRangeId, StringComparer.Ordinal) .Select(group => this.ToPartitionAddressAndRange(collection.ResourceId, @group.ToList(), inNetworkRequest)); foreach (Tuple <PartitionKeyRangeIdentity, PartitionAddressInformation> addressInfo in addressInfos) { this.serverPartitionAddressCache.Set( new PartitionKeyRangeIdentity(collection.ResourceId, addressInfo.Item1.PartitionKeyRangeId), addressInfo.Item2); } } } }