public virtual async Task <TransactionalBatchOperationResult> AddAsync(
            ItemBatchOperation operation,
            ITrace trace,
            ItemRequestOptions itemRequestOptions = null,
            CancellationToken cancellationToken   = default)
        {
            if (operation == null)
            {
                throw new ArgumentNullException(nameof(operation));
            }

            await this.ValidateOperationAsync(operation, itemRequestOptions, cancellationToken);

            string resolvedPartitionKeyRangeId = await this.ResolvePartitionKeyRangeIdAsync(
                operation,
                trace,
                cancellationToken).ConfigureAwait(false);

            BatchAsyncStreamer        streamer = this.GetOrAddStreamerForPartitionKeyRange(resolvedPartitionKeyRangeId);
            ItemBatchOperationContext context  = new ItemBatchOperationContext(
                resolvedPartitionKeyRangeId,
                trace,
                BatchAsyncContainerExecutor.GetRetryPolicy(this.cosmosContainer, operation.OperationType, this.retryOptions));

            operation.AttachContext(context);
            streamer.Add(operation);
            return(await context.OperationTask);
        }
        private BatchAsyncStreamer GetOrAddStreamerForPartitionKeyRange(string partitionKeyRangeId)
        {
            if (this.streamersByPartitionKeyRange.TryGetValue(partitionKeyRangeId, out BatchAsyncStreamer streamer))
            {
                return(streamer);
            }
            SemaphoreSlim      limiter     = this.GetOrAddLimiterForPartitionKeyRange(partitionKeyRangeId);
            BatchAsyncStreamer newStreamer = new BatchAsyncStreamer(
                this.maxServerRequestOperationCount,
                this.maxServerRequestBodyLength,
                this.timerWheel,
                limiter,
                this.defaultMaxDegreeOfConcurrency,
                this.cosmosClientContext.SerializerCore,
                this.ExecuteAsync,
                this.ReBatchAsync,
                this.cosmosClientContext);

            if (!this.streamersByPartitionKeyRange.TryAdd(partitionKeyRangeId, newStreamer))
            {
                newStreamer.Dispose();
            }

            return(this.streamersByPartitionKeyRange[partitionKeyRangeId]);
        }
        private async Task ReBatchAsync(
            ItemBatchOperation operation,
            CancellationToken cancellationToken)
        {
            string resolvedPartitionKeyRangeId = await this.ResolvePartitionKeyRangeIdAsync(operation, cancellationToken).ConfigureAwait(false);

            BatchAsyncStreamer streamer = this.GetOrAddStreamerForPartitionKeyRange(resolvedPartitionKeyRangeId);

            streamer.Add(operation);
        }
        private async Task ReBatchAsync(
            ItemBatchOperation operation,
            CancellationToken cancellationToken)
        {
            using (ITrace trace = Tracing.Trace.GetRootTrace("Batch Retry Async", TraceComponent.Batch, Tracing.TraceLevel.Verbose))
            {
                string resolvedPartitionKeyRangeId = await this.ResolvePartitionKeyRangeIdAsync(operation, trace, cancellationToken).ConfigureAwait(false);

                operation.Context.ReRouteOperation(resolvedPartitionKeyRangeId, trace);
                BatchAsyncStreamer streamer = this.GetOrAddStreamerForPartitionKeyRange(resolvedPartitionKeyRangeId);
                streamer.Add(operation);
            }
        }
示例#5
0
        public virtual async Task <TransactionalBatchOperationResult> AddAsync(
            ItemBatchOperation operation,
            ITrace trace,
            ItemRequestOptions itemRequestOptions = null,
            CancellationToken cancellationToken   = default)
        {
            if (operation == null)
            {
                throw new ArgumentNullException(nameof(operation));
            }

            await this.ValidateOperationAsync(operation, itemRequestOptions, cancellationToken);

            string resolvedPartitionKeyRangeId = await this.ResolvePartitionKeyRangeIdAsync(
                operation,
                trace,
                cancellationToken).ConfigureAwait(false);

            BatchAsyncStreamer streamer = this.GetOrAddStreamerForPartitionKeyRange(resolvedPartitionKeyRangeId);

            ItemBatchOperationContext context = new ItemBatchOperationContext(
                resolvedPartitionKeyRangeId,
                trace,
                BatchAsyncContainerExecutor.GetRetryPolicy(this.cosmosContainer, operation.OperationType, this.retryOptions));

            if (itemRequestOptions != null && itemRequestOptions.AddRequestHeaders != null)
            {
                // get the header value if any, passed by the encryption package.
                Headers encryptionHeaders = new Headers();
                itemRequestOptions.AddRequestHeaders?.Invoke(encryptionHeaders);

                // make sure we set the Intended Collection Rid header when we have encrypted payload.
                // This primarily would allow CosmosDB Encryption package to detect change in container referenced by a Client
                // and prevent creating data with wrong Encryption Policy.
                if (encryptionHeaders.TryGetValue(HttpConstants.HttpHeaders.IsClientEncrypted, out string encrypted))
                {
                    context.IsClientEncrypted = bool.Parse(encrypted);

                    if (context.IsClientEncrypted && encryptionHeaders.TryGetValue(WFConstants.BackendHeaders.IntendedCollectionRid, out string ridValue))
                    {
                        context.IntendedCollectionRidValue = ridValue;
                    }
                }
            }

            operation.AttachContext(context);
            streamer.Add(operation);
            return(await context.OperationTask);
        }
示例#6
0
        private BatchAsyncStreamer GetOrAddStreamerForPartitionKeyRange(string partitionKeyRangeId)
        {
            if (this.streamersByPartitionKeyRange.TryGetValue(partitionKeyRangeId, out BatchAsyncStreamer streamer))
            {
                return(streamer);
            }

            BatchAsyncStreamer newStreamer = new BatchAsyncStreamer(this.maxServerRequestOperationCount, this.maxServerRequestBodyLength, this.dispatchTimerInSeconds, this.timerPool, this.cosmosClientContext.CosmosSerializer, this.ExecuteAsync, this.ReBatchAsync);

            if (!this.streamersByPartitionKeyRange.TryAdd(partitionKeyRangeId, newStreamer))
            {
                newStreamer.Dispose();
            }

            return(this.streamersByPartitionKeyRange[partitionKeyRangeId]);
        }
        public async Task <BatchOperationResult> AddAsync(
            ItemBatchOperation operation,
            ItemRequestOptions itemRequestOptions = null,
            CancellationToken cancellationToken   = default(CancellationToken))
        {
            if (operation == null)
            {
                throw new ArgumentNullException(nameof(operation));
            }

            await this.ValidateOperationAsync(operation, itemRequestOptions, cancellationToken);

            string resolvedPartitionKeyRangeId = await this.ResolvePartitionKeyRangeIdAsync(operation, cancellationToken).ConfigureAwait(false);

            BatchAsyncStreamer        streamer = this.GetOrAddStreamerForPartitionKeyRange(resolvedPartitionKeyRangeId);
            ItemBatchOperationContext context  = new ItemBatchOperationContext(resolvedPartitionKeyRangeId);

            operation.AttachContext(context);
            streamer.Add(operation);
            return(await context.Task);
        }