/// <summary>
        /// Gets the result of the operation at the provided index in the batch - the returned result has a Resource of provided type.
        /// </summary>
        /// <typeparam name="T">Type to which the Resource in the operation result needs to be deserialized to, when present.</typeparam>
        /// <param name="index">0-based index of the operation in the batch whose result needs to be returned.</param>
        /// <returns>Result of batch operation that contains a Resource deserialized to specified type.</returns>
        public override BatchOperationResult <T> GetOperationResultAtIndex <T>(int index)
        {
            if (index >= this.Count)
            {
                throw new IndexOutOfRangeException();
            }

            BatchOperationResult result = this.resultsByOperationIndex[index];

            T resource = default(T);

            if (result.ResourceStream != null)
            {
                resource = this.Serializer.FromStream <T>(result.ResourceStream);
            }

            return(new BatchOperationResult <T>(result, resource));
        }
        private async Task <ResponseMessage> ProcessResourceOperationAsBulkStreamAsync(
            Uri resourceUri,
            ResourceType resourceType,
            OperationType operationType,
            RequestOptions requestOptions,
            ContainerCore cosmosContainerCore,
            PartitionKey partitionKey,
            string itemId,
            Stream streamPayload,
            Action <RequestMessage> requestEnricher,
            CancellationToken cancellationToken)
        {
            ItemRequestOptions      itemRequestOptions      = requestOptions as ItemRequestOptions;
            BatchItemRequestOptions batchItemRequestOptions = BatchItemRequestOptions.FromItemRequestOptions(itemRequestOptions);
            ItemBatchOperation      itemBatchOperation      = new ItemBatchOperation(operationType, /* index */ 0, partitionKey, itemId, streamPayload, batchItemRequestOptions);
            BatchOperationResult    batchOperationResult    = await cosmosContainerCore.BatchExecutor.AddAsync(itemBatchOperation, itemRequestOptions, cancellationToken);

            return(batchOperationResult.ToResponseMessage());
        }
        private static Result ReadOperationResult(ref RowReader reader, out BatchOperationResult batchOperationResult)
        {
            batchOperationResult = new BatchOperationResult();
            while (reader.Read())
            {
                Result r;
                switch (reader.Path)
                {
                case "statusCode":
                    r = reader.ReadInt32(out int statusCode);
                    if (r != Result.Success)
                    {
                        return(r);
                    }

                    batchOperationResult.StatusCode = (HttpStatusCode)statusCode;
                    break;

                case "subStatusCode":
                    r = reader.ReadInt32(out int subStatusCode);
                    if (r != Result.Success)
                    {
                        return(r);
                    }

                    batchOperationResult.SubStatusCode = (SubStatusCodes)subStatusCode;
                    break;

                case "eTag":
                    r = reader.ReadString(out string eTag);
                    if (r != Result.Success)
                    {
                        return(r);
                    }

                    batchOperationResult.ETag = eTag;
                    break;

                case "resourceBody":
                    r = reader.ReadBinary(out byte[] resourceBody);
                    if (r != Result.Success)
                    {
                        return(r);
                    }

                    batchOperationResult.ResourceStream = new MemoryStream(
                        buffer: resourceBody, index: 0, count: resourceBody.Length, writable: false, publiclyVisible: true);
                    break;

                case "retryAfterMilliseconds":
                    r = reader.ReadUInt32(out uint retryAfterMilliseconds);
                    if (r != Result.Success)
                    {
                        return(r);
                    }

                    batchOperationResult.RetryAfter = TimeSpan.FromMilliseconds(retryAfterMilliseconds);
                    break;
                }
            }

            return(Result.Success);
        }
        public virtual async Task DispatchAsync(CancellationToken cancellationToken = default(CancellationToken))
        {
            this.interlockIncrementCheck.EnterLockCheck();

            PartitionKeyRangeServerBatchRequest serverRequest = null;
            ArraySegment <ItemBatchOperation>   pendingOperations;

            try
            {
                try
                {
                    // HybridRow serialization might leave some pending operations out of the batch
                    Tuple <PartitionKeyRangeServerBatchRequest, ArraySegment <ItemBatchOperation> > createRequestResponse = await this.CreateServerRequestAsync(cancellationToken);

                    serverRequest     = createRequestResponse.Item1;
                    pendingOperations = createRequestResponse.Item2;
                    // Any overflow goes to a new batch
                    foreach (ItemBatchOperation operation in pendingOperations)
                    {
                        await this.retrier(operation, cancellationToken);
                    }
                }
                catch (Exception ex)
                {
                    // Exceptions happening during request creation, fail the entire list
                    foreach (ItemBatchOperation itemBatchOperation in this.batchOperations)
                    {
                        itemBatchOperation.Context.Fail(this, ex);
                    }

                    throw;
                }

                try
                {
                    PartitionKeyRangeBatchExecutionResult result = await this.executor(serverRequest, cancellationToken);

                    if (result.IsSplit())
                    {
                        foreach (ItemBatchOperation operationToRetry in result.Operations)
                        {
                            await this.retrier(operationToRetry, cancellationToken);
                        }

                        return;
                    }

                    using (PartitionKeyRangeBatchResponse batchResponse = new PartitionKeyRangeBatchResponse(serverRequest.Operations.Count, result.ServerResponse, this.cosmosSerializer))
                    {
                        foreach (ItemBatchOperation itemBatchOperation in batchResponse.Operations)
                        {
                            BatchOperationResult response = batchResponse[itemBatchOperation.OperationIndex];
                            itemBatchOperation.Context.Complete(this, response);
                        }
                    }
                }
                catch (Exception ex)
                {
                    // Exceptions happening during execution fail all the Tasks part of the request (excluding overflow)
                    foreach (ItemBatchOperation itemBatchOperation in serverRequest.Operations)
                    {
                        itemBatchOperation.Context.Fail(this, ex);
                    }

                    throw;
                }
            }
            catch (Exception ex)
            {
                DefaultTrace.TraceError("Exception during BatchAsyncBatcher: {0}", ex);
            }
            finally
            {
                this.batchOperations.Clear();
                this.dispached = true;
            }
        }
Пример #5
0
        private static Result ReadOperationResult(ref RowReader reader, out BatchOperationResult batchOperationResult)
        {
            batchOperationResult = new BatchOperationResult();
            while (reader.Read())
            {
                Result r;
                switch (reader.Path)
                {
                case "statusCode":
                    r = reader.ReadInt32(out int statusCode);
                    if (r != Result.Success)
                    {
                        return(r);
                    }

                    batchOperationResult.StatusCode = (HttpStatusCode)statusCode;
                    break;

                case "subStatusCode":
                    r = reader.ReadInt32(out int subStatusCode);
                    if (r != Result.Success)
                    {
                        return(r);
                    }

                    batchOperationResult.SubStatusCode = (SubStatusCodes)subStatusCode;
                    break;

                case "eTag":
                    r = reader.ReadString(out string eTag);
                    if (r != Result.Success)
                    {
                        return(r);
                    }

                    batchOperationResult.ETag = eTag;
                    break;

                case "resourceBody":
                    r = reader.ReadBinary(out byte[] resourceBody);
                    if (r != Result.Success)
                    {
                        return(r);
                    }

                    batchOperationResult.ResourceStream = new MemoryStream(
                        buffer: resourceBody, index: 0, count: resourceBody.Length, writable: false, publiclyVisible: true);
                    break;

                case "requestCharge":
                    r = reader.ReadFloat64(out double requestCharge);
                    if (r != Result.Success)
                    {
                        return(r);
                    }

                    // Round request charge to 2 decimals on the operation results
                    // similar to how we round them for the full response.
                    batchOperationResult.RequestCharge = Math.Round(requestCharge, 2);
                    break;

                case "retryAfterMilliseconds":
                    r = reader.ReadUInt32(out uint retryAfterMilliseconds);
                    if (r != Result.Success)
                    {
                        return(r);
                    }

                    batchOperationResult.RetryAfter = TimeSpan.FromMilliseconds(retryAfterMilliseconds);
                    break;
                }
            }

            return(Result.Success);
        }