/// <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; } }
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); }