/// <summary> /// Get the next set of results from the cosmos service /// </summary> /// <param name="cancellationToken">(Optional) <see cref="CancellationToken"/> representing request cancellation.</param> /// <returns>A query response from cosmos service</returns> public override Task <ResponseMessage> ReadNextAsync(CancellationToken cancellationToken = default) { CosmosDiagnosticsContext diagnostics = CosmosDiagnosticsContext.Create(this.requestOptions); using (diagnostics.CreateOverallScope("FeedReadNextAsync")) { return(this.ReadNextInternalAsync(diagnostics, cancellationToken)); } }
// Extracted partition key might be invalid as CollectionCache might be stale. // Stale collection cache is refreshed through PartitionKeyMismatchRetryPolicy // and partition-key is extracted again. internal async Task <ResponseMessage> ExtractPartitionKeyAndProcessItemStreamAsync <T>( PartitionKey?partitionKey, string itemId, T item, OperationType operationType, RequestOptions requestOptions, CancellationToken cancellationToken) { CosmosDiagnosticsContext diagnosticsContext = CosmosDiagnosticsContext.Create(requestOptions); using (diagnosticsContext.CreateOverallScope("ItemStream")) { Stream itemStream; using (diagnosticsContext.CreateScope("ItemSerialize")) { itemStream = this.ClientContext.SerializerCore.ToStream <T>(item); } // User specified PK value, no need to extract it if (partitionKey.HasValue) { return(await this.ProcessItemStreamAsync( partitionKey, itemId, itemStream, operationType, requestOptions, diagnosticsScope : diagnosticsContext, cancellationToken : cancellationToken)); } PartitionKeyMismatchRetryPolicy requestRetryPolicy = null; while (true) { using (diagnosticsContext.CreateScope("ExtractPkValue")) { partitionKey = await this.GetPartitionKeyValueFromStreamAsync(itemStream, cancellationToken); } ResponseMessage responseMessage = await this.ProcessItemStreamAsync( partitionKey, itemId, itemStream, operationType, requestOptions, diagnosticsScope : diagnosticsContext, cancellationToken : cancellationToken); if (responseMessage.IsSuccessStatusCode) { return(responseMessage); } if (requestRetryPolicy == null) { requestRetryPolicy = new PartitionKeyMismatchRetryPolicy(await this.ClientContext.DocumentClient.GetCollectionCacheAsync(), null); } ShouldRetryResult retryResult = await requestRetryPolicy.ShouldRetryAsync(responseMessage, cancellationToken); if (!retryResult.ShouldRetry) { return(responseMessage); } } } }
internal async Task <ResponseMessage> ProcessItemStreamAsync( PartitionKey?partitionKey, string itemId, Stream streamPayload, OperationType operationType, ItemRequestOptions requestOptions, CosmosDiagnosticsContext diagnosticsContext, CancellationToken cancellationToken) { if (requestOptions != null && requestOptions.IsEffectivePartitionKeyRouting) { partitionKey = null; } ContainerCore.ValidatePartitionKey(partitionKey, requestOptions); Uri resourceUri = this.GetResourceUri(requestOptions, operationType, itemId); if (diagnosticsContext == null) { diagnosticsContext = CosmosDiagnosticsContext.Create(requestOptions); } using (diagnosticsContext.CreateOverallScope("ProcessItemStream")) { if (requestOptions != null && requestOptions.EncryptionOptions != null) { if (streamPayload == null) { throw new ArgumentException(ClientResources.InvalidRequestWithEncryptionOptions); } using (diagnosticsContext.CreateScope("Encrypt")) { streamPayload = await this.ClientContext.EncryptionProcessor.EncryptAsync( streamPayload, requestOptions.EncryptionOptions, (DatabaseCore)this.Database, this.ClientContext.ClientOptions.EncryptionKeyWrapProvider, diagnosticsContext, cancellationToken); } } ResponseMessage responseMessage = await this.ClientContext.ProcessResourceOperationStreamAsync( resourceUri : resourceUri, resourceType : ResourceType.Document, operationType : operationType, requestOptions : requestOptions, cosmosContainerCore : this, partitionKey : partitionKey, itemId : itemId, streamPayload : streamPayload, requestEnricher : null, diagnosticsScope : diagnosticsContext, cancellationToken : cancellationToken); if (responseMessage.Content != null && this.ClientContext.ClientOptions.EncryptionKeyWrapProvider != null) { using (diagnosticsContext.CreateScope("Decrypt")) { responseMessage.Content = await this.ClientContext.EncryptionProcessor.DecryptAsync( responseMessage.Content, (DatabaseCore)this.Database, this.ClientContext.ClientOptions.EncryptionKeyWrapProvider, diagnosticsContext, cancellationToken); } } return(responseMessage); } }