Esempio n. 1
0
        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);
                    }
                }
            }
        }