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)); }
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); }); }
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))); }
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; }
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) { }
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; }
// 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(); }
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; }
public DocumentQuery( IDocumentQueryClient client, ResourceType resourceTypeEnum, Type resourceType, string documentsFeedOrDatabaseLink, FeedOptions feedOptions, object partitionKey = null) : this( client, resourceTypeEnum, resourceType, documentsFeedOrDatabaseLink, null, feedOptions, partitionKey) { }
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)); }
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; }
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; }
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)); }
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))); }
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)); }
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)); }
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); }
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)); }
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)); }