public static ProxyDocumentQueryExecutionContext Create(
            IDocumentQueryClient client,
            ResourceType resourceTypeEnum,
            Type resourceType,
            Expression expression,
            FeedOptions feedOptions,
            string resourceLink,
            CancellationToken token,
            ContainerProperties collection,
            bool isContinuationExpected,
            Guid correlatedActivityId)
        {
            token.ThrowIfCancellationRequested();
            DocumentQueryExecutionContextBase.InitParams constructorParams = new DocumentQueryExecutionContextBase.InitParams(client, resourceTypeEnum, resourceType, expression, feedOptions, resourceLink, false, correlatedActivityId);
            IDocumentQueryExecutionContext innerExecutionContext           =
                new DefaultDocumentQueryExecutionContext(constructorParams, isContinuationExpected);

            return(new ProxyDocumentQueryExecutionContext(innerExecutionContext, client,
                                                          resourceTypeEnum,
                                                          resourceType,
                                                          expression,
                                                          feedOptions,
                                                          resourceLink,
                                                          collection,
                                                          isContinuationExpected,
                                                          correlatedActivityId));
        }
Пример #2
0
 private OrderByDocumentQueryExecutionContext(
     IDocumentQueryClient client,
     ResourceType resourceTypeEnum,
     Type resourceType,
     Expression expression,
     FeedOptions feedOptions,
     string resourceLink,
     string rewrittenQuery,
     bool isContinuationExpected,
     bool getLazyFeedResponse,
     OrderByConsumeComparer consumeComparer,
     string collectionRid,
     Guid correlatedActivityId) :
     base(
         client,
         resourceTypeEnum,
         resourceType,
         expression,
         feedOptions,
         resourceLink,
         rewrittenQuery,
         correlatedActivityId,
         isContinuationExpected: isContinuationExpected,
         getLazyFeedResponse: getLazyFeedResponse,
         isDynamicPageSizeAllowed: true)
 {
     this.collectionRid = collectionRid;
     this.documentProducerConsumerQueue = new PriorityQueue <DocumentProducer <OrderByQueryResult> >(consumeComparer);
     this.filters         = new Dictionary <string, string>();
     this.consumeComparer = consumeComparer;
 }
 /// <summary>
 /// Callback to create a child document producer tree based on the partition key range.
 /// </summary>
 /// <param name="createRequestFunc">Callback to create a request.</param>
 /// <param name="executeRequestFunc">Callback to execute a request.</param>
 /// <param name="createRetryPolicyFunc">Callback to create a retry policy.</param>
 /// <param name="produceAsyncCompleteCallback">Callback to invoke once a fetch finishes.</param>
 /// <param name="documentProducerTreeComparer">Comparer to determine, which tree to produce from.</param>
 /// <param name="equalityComparer">Comparer to see if we need to return the continuation token for a partition.</param>
 /// <param name="documentClient">The client</param>
 /// <param name="deferFirstPage">Whether or not to defer fetching the first page.</param>
 /// <param name="collectionRid">The collection to drain from.</param>
 /// <param name="initialPageSize">The initial page size.</param>
 /// <returns>A function that given a partition key range and continuation token will create a document producer.</returns>
 private static Func <PartitionKeyRange, string, DocumentProducerTree> CreateDocumentProducerTreeCallback(
     Func <PartitionKeyRange, string, int, DocumentServiceRequest> createRequestFunc,
     Func <DocumentServiceRequest, CancellationToken, Task <FeedResponse <CosmosElement> > > executeRequestFunc,
     Func <IDocumentClientRetryPolicy> createRetryPolicyFunc,
     Action <DocumentProducerTree, int, double, QueryMetrics, long, CancellationToken> produceAsyncCompleteCallback,
     IComparer <DocumentProducerTree> documentProducerTreeComparer,
     IEqualityComparer <CosmosElement> equalityComparer,
     IDocumentQueryClient documentClient,
     bool deferFirstPage,
     string collectionRid,
     long initialPageSize = 50)
 {
     return((partitionKeyRange, continuationToken) =>
     {
         return new DocumentProducerTree(
             partitionKeyRange,
             createRequestFunc,
             executeRequestFunc,
             createRetryPolicyFunc,
             produceAsyncCompleteCallback,
             documentProducerTreeComparer,
             equalityComparer,
             documentClient,
             deferFirstPage,
             collectionRid,
             initialPageSize,
             continuationToken);
     });
 }
Пример #4
0
 public DefaultDocumentQueryExecutionContext(
     IDocumentQueryClient client,
     ResourceType resourceTypeEnum,
     Type resourceType,
     Expression expression,
     FeedOptions feedOptions,
     string resourceLink,
     bool isContinuationExpected,
     Guid correlatedActivityId) :
     base(
         client,
         resourceTypeEnum,
         resourceType,
         expression,
         feedOptions,
         resourceLink,
         false,
         correlatedActivityId)
 {
     this.isContinuationExpected = isContinuationExpected;
     this.fetchSchedulingMetrics = new SchedulingStopwatch();
     this.fetchSchedulingMetrics.Ready();
     this.providedRangesCache            = new Dictionary <string, IReadOnlyList <Range <string> > >();
     this.fetchExecutionRangeAccumulator = new FetchExecutionRangeAccumulator(singlePartitionKeyId);
     this.retries = -1;
     this.partitionRoutingHelper = new PartitionRoutingHelper();
 }
        protected DocumentQueryExecutionContextBase(
            IDocumentQueryClient client,
            ResourceType resourceTypeEnum,
            Type resourceType,
            Expression expression,
            FeedOptions feedOptions,
            string resourceLink,
            bool getLazyFeedResponse,
            Guid correlatedActivityId)
        {
            if (client == null)
            {
                throw new ArgumentNullException("client");
            }

            if (feedOptions == null)
            {
                throw new ArgumentNullException("feedOptions");
            }

            this.client                = client;
            this.resourceTypeEnum      = resourceTypeEnum;
            this.resourceType          = resourceType;
            this.expression            = expression;
            this.feedOptions           = feedOptions;
            this.resourceLink          = resourceLink;
            this.getLazyFeedResponse   = getLazyFeedResponse;
            this.isExpressionEvaluated = false;
            this.correlatedActivityId  = correlatedActivityId;
        }
        public static Task <ProxyDocumentQueryExecutionContext> CreateAsync(
            IDocumentQueryClient client,
            ResourceType resourceTypeEnum,
            Type resourceType,
            Expression expression,
            FeedOptions feedOptions,
            string resourceLink,
            CancellationToken token,
            CosmosContainerSettings collection,
            bool isContinuationExpected,
            Guid correlatedActivityId)
        {
            token.ThrowIfCancellationRequested();

            IDocumentQueryExecutionContext innerExecutionContext =
                new DefaultDocumentQueryExecutionContext(
                    client,
                    resourceTypeEnum,
                    resourceType,
                    expression,
                    feedOptions,
                    resourceLink,
                    isContinuationExpected,
                    correlatedActivityId);

            return(Task.FromResult(new ProxyDocumentQueryExecutionContext(innerExecutionContext, client,
                                                                          resourceTypeEnum,
                                                                          resourceType,
                                                                          expression,
                                                                          feedOptions,
                                                                          resourceLink,
                                                                          collection,
                                                                          isContinuationExpected,
                                                                          correlatedActivityId)));
        }
Пример #7
0
 private ParallelDocumentQueryExecutionContext(
     IDocumentQueryClient client,
     ResourceType resourceTypeEnum,
     Type resourceType,
     Expression expression,
     FeedOptions feedOptions,
     string resourceLink,
     string rewrittenQuery,
     bool isContinuationExpected,
     bool getLazyFeedResponse,
     string collectionRid,
     Guid correlatedActivityId) :
     base(
         client,
         resourceTypeEnum,
         resourceType,
         expression,
         feedOptions,
         resourceLink,
         rewrittenQuery,
         correlatedActivityId,
         isContinuationExpected,
         getLazyFeedResponse,
         isDynamicPageSizeAllowed: false)
 {
     this.collectionRid = collectionRid;
     this.documentProducerPositionCache = new Dictionary <string, int>();
     this.taskPriorityFunc = (producer) => this.documentProducerPositionCache[producer.TargetRange.MinInclusive];
 }
        private ProxyDocumentQueryExecutionContext(
            IDocumentQueryExecutionContext innerExecutionContext,
            IDocumentQueryClient client,
            ResourceType resourceTypeEnum,
            Type resourceType,
            Expression expression,
            FeedOptions feedOptions,
            string resourceLink,
            ContainerProperties collection,
            bool isContinuationExpected,
            Guid correlatedActivityId)
        {
            this.innerExecutionContext = innerExecutionContext;

            this.client           = client;
            this.resourceTypeEnum = resourceTypeEnum;
            this.resourceType     = resourceType;
            this.expression       = expression;
            this.feedOptions      = feedOptions;
            this.resourceLink     = resourceLink;

            this.collection             = collection;
            this.isContinuationExpected = isContinuationExpected;

            this.correlatedActivityId = correlatedActivityId;
        }
Пример #9
0
 internal CosmosQueryClientCore(
     CosmosClientContext clientContext,
     ContainerCore cosmosContainerCore)
 {
     this.clientContext       = clientContext ?? throw new ArgumentException(nameof(clientContext));
     this.cosmosContainerCore = cosmosContainerCore ?? throw new ArgumentException(nameof(cosmosContainerCore));
     this.DocumentQueryClient = clientContext.DocumentQueryClient ?? throw new ArgumentException(nameof(clientContext));
 }
 public TestQueryExecutionContext(
     IDocumentQueryClient client,
     ResourceType resourceTypeEnum,
     Type resourceType,
     Expression expression,
     FeedOptions feedOptions,
     string resourceLink,
     bool getLazyFeedResponse,
     Guid correlatedActivityId)
     : base(client, resourceTypeEnum, resourceType, expression, feedOptions, resourceLink, getLazyFeedResponse, correlatedActivityId)
 {
 }
Пример #11
0
 protected DocumentQueryExecutionContextBase(
     InitParams initParams)
 {
     this.client                = initParams.Client;
     this.resourceTypeEnum      = initParams.ResourceTypeEnum;
     this.resourceType          = initParams.ResourceType;
     this.expression            = initParams.Expression;
     this.feedOptions           = initParams.FeedOptions;
     this.resourceLink          = initParams.ResourceLink;
     this.getLazyFeedResponse   = initParams.GetLazyFeedResponse;
     this.correlatedActivityId  = initParams.CorrelatedActivityId;
     this.isExpressionEvaluated = false;
 }
Пример #12
0
        // Root Query.
        public DocumentQuery(
            IDocumentQueryClient client,
            ResourceType resourceTypeEnum,
            Type resourceType,
            string documentsFeedOrDatabaseLink,
            Expression expression,
            FeedOptions feedOptions,
            object partitionKey = null)
        {
            if (client == null)
            {
                throw new ArgumentNullException("client");
            }

            this.client                      = client;
            this.resourceTypeEnum            = resourceTypeEnum;
            this.resourceType                = resourceType;
            this.documentsFeedOrDatabaseLink = documentsFeedOrDatabaseLink;
            this.feedOptions                 = feedOptions == null ? new FeedOptions() : new FeedOptions(feedOptions);

            // Swapping out negative values in feedOptions for int.MaxValue
            if (this.feedOptions.MaxBufferedItemCount < 0)
            {
                this.feedOptions.MaxBufferedItemCount = int.MaxValue;
            }

            if (this.feedOptions.MaxDegreeOfParallelism < 0)
            {
                this.feedOptions.MaxDegreeOfParallelism = int.MaxValue;
            }

            if (this.feedOptions.MaxItemCount < 0)
            {
                this.feedOptions.MaxItemCount = int.MaxValue;
            }

            this.partitionKey = partitionKey;

            this.expression    = expression ?? Expression.Constant(this);
            this.queryProvider = new DocumentQueryProvider(
                client,
                resourceTypeEnum,
                resourceType,
                documentsFeedOrDatabaseLink,
                feedOptions,
                partitionKey,
                this.client.OnExecuteScalarQueryCallback);
            this.executeNextAysncMetrics = new SchedulingStopwatch();
            this.executeNextAysncMetrics.Ready();
            this.correlatedActivityId = Guid.NewGuid();
        }
Пример #13
0
        public static async Task <OrderByDocumentQueryExecutionContext> CreateAsync(
            IDocumentQueryClient client,
            ResourceType resourceTypeEnum,
            Type resourceType,
            Expression expression,
            FeedOptions feedOptions,
            string resourceLink,
            string collectionRid,
            PartitionedQueryExecutionInfo partitionedQueryExecutionInfo,
            List <PartitionKeyRange> partitionKeyRanges,
            int initialPageSize,
            bool isContinuationExpected,
            bool getLazyFeedResponse,
            string requestContinuation,
            CancellationToken token,
            Guid correlatedActivityId)
        {
            Debug.Assert(
                partitionedQueryExecutionInfo.QueryInfo.HasOrderBy,
                "OrderBy~Context must have order by query info.");

            OrderByDocumentQueryExecutionContext context = new OrderByDocumentQueryExecutionContext(
                client,
                resourceTypeEnum,
                resourceType,
                expression,
                feedOptions,
                resourceLink,
                partitionedQueryExecutionInfo.QueryInfo.RewrittenQuery,
                isContinuationExpected,
                getLazyFeedResponse,
                new OrderByConsumeComparer(partitionedQueryExecutionInfo.QueryInfo.OrderBy),
                collectionRid,
                correlatedActivityId);

            await context.InitializeAsync(
                collectionRid,
                partitionedQueryExecutionInfo.QueryRanges,
                partitionKeyRanges,
                partitionedQueryExecutionInfo.QueryInfo.OrderBy,
                partitionedQueryExecutionInfo.QueryInfo.OrderByExpressions,
                initialPageSize,
                requestContinuation,
                token);

            return(context);
        }
 internal CosmosClientContextCore(
     CosmosClient client,
     CosmosClientConfiguration clientConfiguration,
     CosmosJsonSerializer cosmosJsonSerializer,
     CosmosResponseFactory cosmosResponseFactory,
     CosmosRequestHandler requestHandler,
     DocumentClient documentClient,
     IDocumentQueryClient documentQueryClient)
 {
     this.Client = client;
     this.ClientConfiguration = clientConfiguration;
     this.JsonSerializer      = cosmosJsonSerializer;
     this.ResponseFactory     = cosmosResponseFactory;
     this.RequestHandler      = requestHandler;
     this.DocumentClient      = documentClient;
     this.DocumentQueryClient = documentQueryClient;
 }
Пример #15
0
 public DocumentQuery(
     IDocumentQueryClient client,
     ResourceType resourceTypeEnum,
     Type resourceType,
     string documentsFeedOrDatabaseLink,
     FeedOptions feedOptions,
     object partitionKey = null) :
     this(
         client,
         resourceTypeEnum,
         resourceType,
         documentsFeedOrDatabaseLink,
         null,
         feedOptions,
         partitionKey)
 {
 }
Пример #16
0
 public DocumentQueryProvider(
     IDocumentQueryClient client,
     ResourceType resourceTypeEnum,
     Type resourceType,
     string documentsFeedOrDatabaseLink,
     FeedOptions feedOptions,
     object partitionKey = null,
     Action <IQueryable> onExecuteScalarQueryCallback = null)
 {
     this.client                       = client;
     this.resourceTypeEnum             = resourceTypeEnum;
     this.resourceType                 = resourceType;
     this.documentsFeedOrDatabaseLink  = documentsFeedOrDatabaseLink;
     this.feedOptions                  = feedOptions;
     this.partitionKey                 = partitionKey;
     this.onExecuteScalarQueryCallback = onExecuteScalarQueryCallback;
 }
        public static async Task <MultiCollectionDocumentQueryExecutionContext> CreateAsync(
            IDocumentQueryClient client,
            ResourceType resourceTypeEnum,
            Type resourceType,
            Expression expression,
            FeedOptions feedOptions,
            IEnumerable <string> documentFeedLinks,
            bool isContinuationExpected,
            CancellationToken token,
            Guid correlatedActivityId)
        {
            if (client == null)
            {
                throw new ArgumentNullException("client");
            }

            if (feedOptions == null)
            {
                throw new ArgumentNullException("feedOptions");
            }

            if (documentFeedLinks == null)
            {
                throw new ArgumentNullException("documentFeedLinks");
            }

            List <IDocumentQueryExecutionContext> childQueryExecutionContexts = new List <IDocumentQueryExecutionContext>();

            foreach (string link in documentFeedLinks)
            {
                childQueryExecutionContexts.Add(await DocumentQueryExecutionContextFactory.CreateDocumentQueryExecutionContextAsync(
                                                    client,
                                                    resourceTypeEnum,
                                                    resourceType,
                                                    expression,
                                                    feedOptions,
                                                    link,
                                                    isContinuationExpected,
                                                    token,
                                                    correlatedActivityId));
            }

            return(new MultiCollectionDocumentQueryExecutionContext(childQueryExecutionContexts));
        }
Пример #18
0
            public InitParams(
                IDocumentQueryClient client,
                ResourceType resourceTypeEnum,
                Type resourceType,
                Expression expression,
                FeedOptions feedOptions,
                string resourceLink,
                bool getLazyFeedResponse,
                Guid correlatedActivityId)
            {
                if (client == null)
                {
                    throw new ArgumentNullException($"{nameof(client)} can not be null.");
                }

                if (resourceType == null)
                {
                    throw new ArgumentNullException($"{nameof(resourceType)} can not be null.");
                }

                if (expression == null)
                {
                    throw new ArgumentNullException($"{nameof(expression)} can not be null.");
                }

                if (feedOptions == null)
                {
                    throw new ArgumentNullException($"{nameof(feedOptions)} can not be null.");
                }

                if (correlatedActivityId == Guid.Empty)
                {
                    throw new ArgumentException($"{nameof(correlatedActivityId)} can not be empty.");
                }

                this.Client               = client;
                this.ResourceTypeEnum     = resourceTypeEnum;
                this.ResourceType         = resourceType;
                this.Expression           = expression;
                this.FeedOptions          = feedOptions;
                this.ResourceLink         = resourceLink;
                this.GetLazyFeedResponse  = getLazyFeedResponse;
                this.CorrelatedActivityId = correlatedActivityId;
            }
Пример #19
0
 internal ClientContextCore(
     CosmosClient client,
     CosmosClientOptions clientOptions,
     CosmosSerializer userJsonSerializer,
     CosmosSerializer defaultJsonSerializer,
     CosmosResponseFactory cosmosResponseFactory,
     RequestInvokerHandler requestHandler,
     DocumentClient documentClient,
     IDocumentQueryClient documentQueryClient)
 {
     this.Client               = client;
     this.ClientOptions        = clientOptions;
     this.CosmosSerializer     = userJsonSerializer;
     this.PropertiesSerializer = defaultJsonSerializer;
     this.ResponseFactory      = cosmosResponseFactory;
     this.RequestHandler       = requestHandler;
     this.DocumentClient       = documentClient;
     this.DocumentQueryClient  = documentQueryClient;
 }
Пример #20
0
 public static async Task <IDocumentQueryExecutionContext> CreateDocumentQueryExecutionContextAsync(
     IDocumentQueryClient client,
     ResourceType resourceTypeEnum,
     Type resourceType,
     Expression expression,
     FeedOptions feedOptions,
     IEnumerable <string> documentFeedLinks,
     bool isContinuationExpected,
     CancellationToken token,
     Guid correlatedActivityId)
 {
     return(await MultiCollectionDocumentQueryExecutionContext.CreateAsync(
                client,
                resourceTypeEnum,
                resourceType,
                expression,
                feedOptions,
                documentFeedLinks,
                isContinuationExpected,
                token,
                correlatedActivityId));
 }
Пример #21
0
 public static Task <DefaultDocumentQueryExecutionContext> CreateAsync(
     IDocumentQueryClient client,
     ResourceType resourceTypeEnum,
     Type resourceType,
     Expression expression,
     FeedOptions feedOptions,
     string resourceLink,
     bool isContinuationExpected,
     CancellationToken cancellationToken,
     Guid correlatedActivityId)
 {
     cancellationToken.ThrowIfCancellationRequested();
     return(Task.FromResult(new DefaultDocumentQueryExecutionContext(
                                client,
                                resourceTypeEnum,
                                resourceType,
                                expression,
                                feedOptions,
                                resourceLink,
                                isContinuationExpected,
                                correlatedActivityId)));
 }
Пример #22
0
 internal static IOrderedQueryable <Document> CreateDocumentQuery(this IDocumentQueryClient client, string collectionLink, FeedOptions feedOptions = null, object partitionKey = null)
 {
     return(new DocumentQuery <Document>(client, ResourceType.Document, typeof(Document), collectionLink, feedOptions, partitionKey));
 }
Пример #23
0
        protected ParallelDocumentQueryExecutionContextBase(
            IDocumentQueryClient client,
            ResourceType resourceTypeEnum,
            Type resourceType,
            Expression expression,
            FeedOptions feedOptions,
            string resourceLink,
            string rewrittenQuery,
            Guid correlatedActivityId,
            bool isContinuationExpected,
            bool getLazyFeedResponse,
            bool isDynamicPageSizeAllowed) :
            base(
                client,
                resourceTypeEnum,
                resourceType,
                expression,
                feedOptions,
                resourceLink,
                getLazyFeedResponse,
                correlatedActivityId)
        {
            this.DocumentProducers = new List <DocumentProducer <T> >();

            this.chargeTracker           = new RequestChargeTracker();
            this.groupedQueryMetrics     = new Dictionary <string, QueryMetrics>();
            this.partitionedQueryMetrics = new ConcurrentBag <Tuple <string, QueryMetrics> >();
            this.responseHeaders         = new StringKeyValueCollection();

            this.actualMaxBufferedItemCount            = Math.Max(this.MaxBufferedItemCount, ParallelQueryConfig.GetConfig().DefaultMaximumBufferSize);
            this.currentAverageNumberOfRequestsPerTask = 1d;

            if (!string.IsNullOrEmpty(rewrittenQuery))
            {
                this.querySpec = new SqlQuerySpec(rewrittenQuery, this.QuerySpec.Parameters);
            }

            this.TaskScheduler                   = new ComparableTaskScheduler(this.GetCurrentMaximumAllowedConcurrentTasks(0));
            this.ShouldPrefetch                  = feedOptions.MaxDegreeOfParallelism != 0;
            this.IsContinuationExpected          = isContinuationExpected;
            this.DefaultContinuationToken        = Guid.NewGuid().ToString();
            this.InitializationSchedulingMetrics = new SchedulingStopwatch();
            this.InitializationSchedulingMetrics.Ready();
            this.CurrentContinuationTokens = new SortedList <DocumentProducer <T>, string>(
                Comparer <DocumentProducer <T> > .Create((producer1, producer2) => string.CompareOrdinal(producer1.TargetRange.MinInclusive, producer2.TargetRange.MinInclusive)));
            this.actualMaxPageSize = this.MaxItemCount.GetValueOrDefault(ParallelQueryConfig.GetConfig().ClientInternalMaxItemCount);

            if (this.actualMaxBufferedItemCount < 0)
            {
                throw new OverflowException("actualMaxBufferedItemCount should never be less than 0");
            }

            if (this.actualMaxBufferedItemCount > int.MaxValue)
            {
                throw new OverflowException("actualMaxBufferedItemCount should never be greater than int.MaxValue");
            }

            if (this.actualMaxPageSize < 0)
            {
                throw new OverflowException("actualMaxPageSize should never be less than 0");
            }

            if (this.actualMaxPageSize > int.MaxValue)
            {
                throw new OverflowException("actualMaxPageSize should never be greater than int.MaxValue");
            }
        }
        public static async Task <IDocumentQueryExecutionContext> CreateDocumentQueryExecutionContextAsync(
            IDocumentQueryClient client,
            ResourceType resourceTypeEnum,
            Type resourceType,
            Expression expression,
            FeedOptions feedOptions,
            string resourceLink,
            bool isContinuationExpected,
            CancellationToken token,
            Guid correlatedActivityId)
        {
            ContainerProperties collection = null;

            if (resourceTypeEnum.IsCollectionChild())
            {
                CollectionCache collectionCache = await client.GetCollectionCacheAsync();

                using (
                    DocumentServiceRequest request = DocumentServiceRequest.Create(
                        OperationType.Query,
                        resourceTypeEnum,
                        resourceLink,
                        AuthorizationTokenType.Invalid)) //this request doesnt actually go to server
                {
                    collection = await collectionCache.ResolveCollectionAsync(request, token);
                }

                if (feedOptions != null && feedOptions.PartitionKey != null && feedOptions.PartitionKey.Equals(Documents.PartitionKey.None))
                {
                    feedOptions.PartitionKey = Documents.PartitionKey.FromInternalKey(collection.GetNoneValue());
                }
            }

            DocumentQueryExecutionContextBase.InitParams constructorParams = new DocumentQueryExecutionContextBase.InitParams(
                client,
                resourceTypeEnum,
                resourceType,
                expression,
                feedOptions,
                resourceLink,
                false,
                correlatedActivityId);

            // For non-Windows platforms(like Linux and OSX) in .NET Core SDK, we cannot use ServiceInterop, so need to bypass in that case.
            // We are also now bypassing this for 32 bit host process running even on Windows as there are many 32 bit apps that will not work without this
            if (CustomTypeExtensions.ByPassQueryParsing())
            {
                // We create a ProxyDocumentQueryExecutionContext that will be initialized with DefaultDocumentQueryExecutionContext
                // which will be used to send the query to Gateway and on getting 400(bad request) with 1004(cross partition query not servable), we initialize it with
                // PipelinedDocumentQueryExecutionContext by providing the partition query execution info that's needed(which we get from the exception returned from Gateway).
                ProxyDocumentQueryExecutionContext proxyQueryExecutionContext =
                    ProxyDocumentQueryExecutionContext.Create(
                        client,
                        resourceTypeEnum,
                        resourceType,
                        expression,
                        feedOptions,
                        resourceLink,
                        token,
                        collection,
                        isContinuationExpected,
                        correlatedActivityId);

                return(proxyQueryExecutionContext);
            }

            DefaultDocumentQueryExecutionContext queryExecutionContext = await DefaultDocumentQueryExecutionContext.CreateAsync(
                constructorParams, isContinuationExpected, token);

            // If isContinuationExpected is false, we want to check if there are aggregates.
            if (
                resourceTypeEnum.IsCollectionChild() &&
                resourceTypeEnum.IsPartitioned() &&
                (feedOptions.EnableCrossPartitionQuery || !isContinuationExpected))
            {
                //todo:elasticcollections this may rely on information from collection cache which is outdated
                //if collection is deleted/created with same name.
                //need to make it not rely on information from collection cache.
                PartitionedQueryExecutionInfo partitionedQueryExecutionInfo = await queryExecutionContext.GetPartitionedQueryExecutionInfoAsync(
                    partitionKeyDefinition : collection.PartitionKey,
                    requireFormattableOrderByQuery : true,
                    isContinuationExpected : isContinuationExpected,
                    allowNonValueAggregateQuery : true,
                    hasLogicalPartitionKey : feedOptions.PartitionKey != null,
                    cancellationToken : token);

                if (DocumentQueryExecutionContextFactory.ShouldCreateSpecializedDocumentQueryExecutionContext(
                        resourceTypeEnum,
                        feedOptions,
                        partitionedQueryExecutionInfo,
                        collection.PartitionKey,
                        isContinuationExpected))
                {
                    List <PartitionKeyRange> targetRanges = await GetTargetPartitionKeyRangesAsync(
                        queryExecutionContext,
                        partitionedQueryExecutionInfo,
                        collection,
                        feedOptions);

                    // Devnote this will get replace by the new v3 to v2 logic
                    throw new NotSupportedException("v2 query excution context is currently not supported.");
                }
            }

            return(queryExecutionContext);
        }
        public static async Task <PipelinedDocumentQueryExecutionContext> CreateAsync(
            IDocumentQueryClient client,
            ResourceType resourceTypeEnum,
            Type resourceType,
            Expression expression,
            FeedOptions feedOptions,
            string resourceLink,
            string collectionRid,
            PartitionedQueryExecutionInfo partitionedQueryExecutionInfo,
            List <PartitionKeyRange> targetRanges,
            int initialPageSize,
            bool isContinuationExpected,
            bool getLazyFeedResponse,
            CancellationToken token,
            Guid correlatedActivityId)
        {
            DefaultTrace.TraceInformation(
                string.Format(
                    CultureInfo.InvariantCulture,
                    "{0}, CorrelatedActivityId: {1} | Pipelined~Context.CreateAsync",
                    DateTime.UtcNow.ToString("o", CultureInfo.InvariantCulture),
                    correlatedActivityId));
            Func <string, Task <IDocumentQueryExecutionComponent> > createComponentFunc;

            QueryInfo queryInfo = partitionedQueryExecutionInfo.QueryInfo;

            if (queryInfo.HasOrderBy)
            {
                createComponentFunc = async(requestContinuation) =>
                {
                    return(await OrderByDocumentQueryExecutionContext.CreateAsync(
                               client,
                               resourceTypeEnum,
                               resourceType,
                               expression,
                               feedOptions,
                               resourceLink,
                               collectionRid,
                               partitionedQueryExecutionInfo,
                               targetRanges,
                               initialPageSize,
                               isContinuationExpected,
                               getLazyFeedResponse,
                               requestContinuation,
                               token,
                               correlatedActivityId));
                };
            }
            else
            {
                createComponentFunc = async(requestContinuation) =>
                {
                    return(await ParallelDocumentQueryExecutionContext.CreateAsync(
                               client,
                               resourceTypeEnum,
                               resourceType,
                               expression,
                               feedOptions,
                               resourceLink,
                               collectionRid,
                               partitionedQueryExecutionInfo,
                               targetRanges,
                               initialPageSize,
                               isContinuationExpected,
                               getLazyFeedResponse,
                               requestContinuation,
                               token,
                               correlatedActivityId));
                };
            }

            if (queryInfo.HasAggregates)
            {
                Func <string, Task <IDocumentQueryExecutionComponent> > createSourceCallback = createComponentFunc;
                createComponentFunc = async(requestContinuation) =>
                {
                    return(await AggregateDocumentQueryExecutionComponent.CreateAsync(
                               queryInfo.Aggregates,
                               requestContinuation,
                               createSourceCallback));
                };
            }

            if (queryInfo.HasDistinct)
            {
                Func <string, Task <IDocumentQueryExecutionComponent> > createSourceCallback = createComponentFunc;
                createComponentFunc = async(requestContinuation) =>
                {
                    return(await DistinctDocumentQueryExecutionComponent.CreateAsync(
                               requestContinuation,
                               createSourceCallback,
                               queryInfo.DistinctType));
                };
            }

            if (queryInfo.HasTop)
            {
                Func <string, Task <IDocumentQueryExecutionComponent> > createSourceCallback = createComponentFunc;
                createComponentFunc = async(requestContinuation) =>
                {
                    return(await TopDocumentQueryExecutionComponent.CreateAsync(
                               queryInfo.Top.Value,
                               requestContinuation,
                               createSourceCallback));
                };
            }

            int actualPageSize = feedOptions.MaxItemCount.GetValueOrDefault(ParallelQueryConfig.GetConfig().ClientInternalPageSize);

            // If this contract changes, make the corresponding change in MongoDocumentClient.QueryInternalAsync
            if (actualPageSize == -1)
            {
                actualPageSize = int.MaxValue;
            }

            return(new PipelinedDocumentQueryExecutionContext(
                       await createComponentFunc(feedOptions.RequestContinuation),
                       Math.Min(actualPageSize, queryInfo.Top.GetValueOrDefault(actualPageSize)),
                       correlatedActivityId));
        }
Пример #26
0
        public static async Task <IDocumentQueryExecutionContext> CreateDocumentQueryExecutionContextAsync(
            IDocumentQueryClient client,
            ResourceType resourceTypeEnum,
            Type resourceType,
            Expression expression,
            FeedOptions feedOptions,
            string resourceLink,
            bool isContinuationExpected,
            CancellationToken token,
            Guid correlatedActivityId)
        {
            DocumentQueryExecutionContextBase.InitParams constructorParams = new DocumentQueryExecutionContextBase.InitParams(
                client,
                resourceTypeEnum,
                resourceType,
                expression,
                feedOptions,
                resourceLink,
                false,
                correlatedActivityId);

            CosmosContainerSettings collection = null;

            if (resourceTypeEnum.IsCollectionChild())
            {
                CollectionCache collectionCache = await client.GetCollectionCacheAsync();

                using (
                    DocumentServiceRequest request = DocumentServiceRequest.Create(
                        OperationType.Query,
                        resourceTypeEnum,
                        resourceLink,
                        AuthorizationTokenType.Invalid)) //this request doesnt actually go to server
                {
                    collection = await collectionCache.ResolveCollectionAsync(request, token);
                }
            }

            // For non-Windows platforms(like Linux and OSX) in .NET Core SDK, we cannot use ServiceInterop, so need to bypass in that case.
            // We are also now bypassing this for 32 bit host process running even on Windows as there are many 32 bit apps that will not work without this
            if (CustomTypeExtensions.ByPassQueryParsing())
            {
                // We create a ProxyDocumentQueryExecutionContext that will be initialized with DefaultDocumentQueryExecutionContext
                // which will be used to send the query to Gateway and on getting 400(bad request) with 1004(cross partition query not servable), we initialize it with
                // PipelinedDocumentQueryExecutionContext by providing the partition query execution info that's needed(which we get from the exception returned from Gateway).
                ProxyDocumentQueryExecutionContext proxyQueryExecutionContext =
                    ProxyDocumentQueryExecutionContext.CreateAsync(
                        client,
                        resourceTypeEnum,
                        resourceType,
                        expression,
                        feedOptions,
                        resourceLink,
                        token,
                        collection,
                        isContinuationExpected,
                        correlatedActivityId);

                return(proxyQueryExecutionContext);
            }

            DefaultDocumentQueryExecutionContext queryExecutionContext = await DefaultDocumentQueryExecutionContext.CreateAsync(
                constructorParams, isContinuationExpected, token);

            // If isContinuationExpected is false, we want to check if there are aggregates.
            if (
                resourceTypeEnum.IsCollectionChild() &&
                resourceTypeEnum.IsPartitioned() &&
                (feedOptions.EnableCrossPartitionQuery || !isContinuationExpected))
            {
                //todo:elasticcollections this may rely on information from collection cache which is outdated
                //if collection is deleted/created with same name.
                //need to make it not rely on information from collection cache.
                PartitionedQueryExecutionInfo partitionedQueryExecutionInfo = await queryExecutionContext.GetPartitionedQueryExecutionInfoAsync(
                    collection.PartitionKey,
                    true,
                    isContinuationExpected,
                    token);

                if (DocumentQueryExecutionContextFactory.ShouldCreateSpecializedDocumentQueryExecutionContext(
                        resourceTypeEnum,
                        feedOptions,
                        partitionedQueryExecutionInfo,
                        collection.PartitionKey,
                        isContinuationExpected))
                {
                    List <PartitionKeyRange> targetRanges;
                    if (!string.IsNullOrEmpty(feedOptions.PartitionKeyRangeId))
                    {
                        targetRanges =
                            new List <PartitionKeyRange>
                        {
                            await queryExecutionContext.GetTargetPartitionKeyRangeById(
                                collection.ResourceId,
                                feedOptions.PartitionKeyRangeId)
                        };
                    }
                    else
                    {
                        List <Range <string> > queryRanges = partitionedQueryExecutionInfo.QueryRanges;
                        if (feedOptions.PartitionKey != null)
                        {
                            queryRanges = new List <Range <string> >
                            {
                                Range <string> .GetPointRange(
                                    feedOptions.PartitionKey.InternalKey.GetEffectivePartitionKeyString(
                                        collection.PartitionKey))
                            };
                        }

                        targetRanges =
                            await queryExecutionContext.GetTargetPartitionKeyRanges(collection.ResourceId, queryRanges);
                    }



                    return(await CreateSpecializedDocumentQueryExecutionContext(
                               constructorParams,
                               partitionedQueryExecutionInfo,
                               targetRanges,
                               collection.ResourceId,
                               isContinuationExpected,
                               token));
                }
            }

            return(queryExecutionContext);
        }
        /// <summary>
        /// Initializes a new instance of the DocumentProducerTree class.
        /// </summary>
        /// <param name="partitionKeyRange">The partition key range.</param>
        /// <param name="createRequestFunc">Callback to create a request.</param>
        /// <param name="executeRequestFunc">Callback to execute a request.</param>
        /// <param name="createRetryPolicyFunc">Callback to create a retry policy.</param>
        /// <param name="produceAsyncCompleteCallback">Callback to invoke once a fetch finishes.</param>
        /// <param name="documentProducerTreeComparer">Comparer to determine, which tree to produce from.</param>
        /// <param name="equalityComparer">Comparer to see if we need to return the continuation token for a partition.</param>
        /// <param name="client">The client</param>
        /// <param name="deferFirstPage">Whether or not to defer fetching the first page.</param>
        /// <param name="collectionRid">The collection to drain from.</param>
        /// <param name="initialPageSize">The initial page size.</param>
        /// <param name="initialContinuationToken">The initial continuation token.</param>
        public DocumentProducerTree(
            PartitionKeyRange partitionKeyRange,
            Func <PartitionKeyRange, string, int, DocumentServiceRequest> createRequestFunc,
            Func <DocumentServiceRequest, CancellationToken, Task <FeedResponse <CosmosElement> > > executeRequestFunc,
            Func <IDocumentClientRetryPolicy> createRetryPolicyFunc,
            Action <DocumentProducerTree, int, double, QueryMetrics, long, CancellationToken> produceAsyncCompleteCallback,
            IComparer <DocumentProducerTree> documentProducerTreeComparer,
            IEqualityComparer <CosmosElement> equalityComparer,
            IDocumentQueryClient client,
            bool deferFirstPage,
            string collectionRid,
            long initialPageSize            = 50,
            string initialContinuationToken = null)
        {
            if (documentProducerTreeComparer == null)
            {
                throw new ArgumentNullException($"{nameof(documentProducerTreeComparer)}");
            }

            if (createRequestFunc == null)
            {
                throw new ArgumentNullException($"{nameof(createRequestFunc)}");
            }

            if (executeRequestFunc == null)
            {
                throw new ArgumentNullException($"{nameof(executeRequestFunc)}");
            }

            if (createRetryPolicyFunc == null)
            {
                throw new ArgumentNullException($"{nameof(createRetryPolicyFunc)}");
            }

            if (produceAsyncCompleteCallback == null)
            {
                throw new ArgumentNullException($"{nameof(produceAsyncCompleteCallback)}");
            }

            if (documentProducerTreeComparer == null)
            {
                throw new ArgumentNullException($"{nameof(documentProducerTreeComparer)}");
            }

            if (equalityComparer == null)
            {
                throw new ArgumentNullException($"{nameof(equalityComparer)}");
            }

            if (client == null)
            {
                throw new ArgumentNullException($"{nameof(client)}");
            }

            if (string.IsNullOrEmpty(collectionRid))
            {
                throw new ArgumentException($"{nameof(collectionRid)} can not be null or empty.");
            }

            this.root = new DocumentProducer(
                partitionKeyRange,
                createRequestFunc,
                executeRequestFunc,
                createRetryPolicyFunc,
                (documentProducer, itemsBuffered, resourceUnitUsage, queryMetrics, requestLength, token) => produceAsyncCompleteCallback(this, itemsBuffered, resourceUnitUsage, queryMetrics, requestLength, token),
                equalityComparer,
                initialPageSize,
                initialContinuationToken);

            this.children       = new PriorityQueue <DocumentProducerTree>(documentProducerTreeComparer, true);
            this.deferFirstPage = deferFirstPage;
            this.client         = client;
            this.collectionRid  = collectionRid;
            this.createDocumentProducerTreeCallback = DocumentProducerTree.CreateDocumentProducerTreeCallback(
                createRequestFunc,
                executeRequestFunc,
                createRetryPolicyFunc,
                produceAsyncCompleteCallback,
                documentProducerTreeComparer,
                equalityComparer,
                client,
                deferFirstPage,
                collectionRid,
                initialPageSize);
            this.executeWithSplitProofingSemaphore = new SemaphoreSlim(1, 1);
        }
Пример #28
0
        public static async Task <IDocumentQueryExecutionContext> CreateSpecializedDocumentQueryExecutionContext(
            IDocumentQueryClient client,
            ResourceType resourceTypeEnum,
            Type resourceType,
            Expression expression,
            FeedOptions feedOptions,
            string resourceLink,
            bool isContinuationExpected,
            PartitionedQueryExecutionInfo partitionedQueryExecutionInfo,
            List <PartitionKeyRange> targetRanges,
            string collectionRid,
            CancellationToken token,
            Guid correlatedActivityId)
        {
            long initialPageSize = feedOptions.MaxItemCount.GetValueOrDefault(ParallelQueryConfig.GetConfig().ClientInternalPageSize);

            if (initialPageSize < -1 || initialPageSize == 0)
            {
                throw new BadRequestException(string.Format(CultureInfo.InvariantCulture, "Invalid MaxItemCount {0}", initialPageSize));
            }

            QueryInfo queryInfo = partitionedQueryExecutionInfo.QueryInfo;

            bool getLazyFeedResponse = queryInfo.HasTop;

            // We need to compute the optimal initial page size for order-by queries
            if (queryInfo.HasOrderBy)
            {
                int top;
                if (queryInfo.HasTop && (top = partitionedQueryExecutionInfo.QueryInfo.Top.Value) > 0)
                {
                    // All partitions should initially fetch about 1/nth of the top value.
                    long pageSizeWithTop = (long)Math.Min(
                        Math.Ceiling(top / (double)targetRanges.Count) * PageSizeFactorForTop,
                        top);

                    if (initialPageSize > 0)
                    {
                        initialPageSize = Math.Min(pageSizeWithTop, initialPageSize);
                    }
                    else
                    {
                        initialPageSize = pageSizeWithTop;
                    }
                }
                else if (isContinuationExpected)
                {
                    if (initialPageSize < 0)
                    {
                        // Max of what the user is willing to buffer and the default (note this is broken if MaxBufferedItemCount = -1)
                        initialPageSize = (long)Math.Max(feedOptions.MaxBufferedItemCount, ParallelQueryConfig.GetConfig().DefaultMaximumBufferSize);
                    }

                    initialPageSize = (long)Math.Min(
                        Math.Ceiling(initialPageSize / (double)targetRanges.Count) * PageSizeFactorForTop,
                        initialPageSize);
                }
            }

            Debug.Assert(initialPageSize > 0 && initialPageSize <= int.MaxValue,
                         string.Format(CultureInfo.InvariantCulture, "Invalid MaxItemCount {0}", initialPageSize));

            return(await PipelinedDocumentQueryExecutionContext.CreateAsync(
                       client,
                       resourceTypeEnum,
                       resourceType,
                       expression,
                       feedOptions,
                       resourceLink,
                       collectionRid,
                       partitionedQueryExecutionInfo,
                       targetRanges,
                       (int)initialPageSize,
                       isContinuationExpected,
                       getLazyFeedResponse,
                       token,
                       correlatedActivityId));
        }
Пример #29
0
 internal static IQueryable <dynamic> CreateDocumentQuery(this IDocumentQueryClient client, string collectionLink, SqlQuerySpec querySpec, FeedOptions feedOptions = null, object partitionKey = null)
 {
     return(new DocumentQuery <Document>(client, ResourceType.Document, typeof(Document), collectionLink, feedOptions, partitionKey).AsSQL(querySpec));
 }