private async Task <ResponseMessage> ProcessResourceOperationAsBulkStreamAsync( Uri resourceUri, ResourceType resourceType, OperationType operationType, RequestOptions requestOptions, ContainerCore cosmosContainerCore, PartitionKey partitionKey, string itemId, Stream streamPayload, CosmosDiagnosticsContext diagnosticsContext, CancellationToken cancellationToken) { ItemRequestOptions itemRequestOptions = requestOptions as ItemRequestOptions; TransactionalBatchItemRequestOptions batchItemRequestOptions = TransactionalBatchItemRequestOptions.FromItemRequestOptions(itemRequestOptions); ItemBatchOperation itemBatchOperation = new ItemBatchOperation( operationType: operationType, operationIndex: 0, partitionKey: partitionKey, id: itemId, resourceStream: streamPayload, requestOptions: batchItemRequestOptions, diagnosticsContext: diagnosticsContext); TransactionalBatchOperationResult batchOperationResult = await cosmosContainerCore.BatchExecutor.AddAsync(itemBatchOperation, itemRequestOptions, cancellationToken); return(batchOperationResult.ToResponseMessage()); }
internal static Result ReadOperationResult(Memory <byte> input, out TransactionalBatchOperationResult batchOperationResult) { RowBuffer row = new RowBuffer(input.Length); if (!row.ReadFrom( input.Span, HybridRowVersion.V1, BatchSchemaProvider.BatchLayoutResolver)) { batchOperationResult = null; return(Result.Failure); } RowReader reader = new RowReader(ref row); Result result = TransactionalBatchOperationResult.ReadOperationResult(ref reader, out batchOperationResult); if (result != Result.Success) { return(result); } // Ensure the mandatory fields were populated if (batchOperationResult.StatusCode == default(HttpStatusCode)) { return(Result.Failure); } return(Result.Success); }
public void CanBeMocked() { Mock <TransactionalBatchOperationResult> mockResult = new Mock <TransactionalBatchOperationResult>(); TransactionalBatchOperationResult result = mockResult.Object; Assert.AreEqual(default(HttpStatusCode), result.StatusCode); }
private async Task <ResponseMessage> ProcessResourceOperationAsBulkStreamAsync( OperationType operationType, RequestOptions requestOptions, ContainerInternal cosmosContainerCore, PartitionKey partitionKey, string itemId, Stream streamPayload, CancellationToken cancellationToken) { this.ThrowIfDisposed(); ItemRequestOptions itemRequestOptions = requestOptions as ItemRequestOptions; TransactionalBatchItemRequestOptions batchItemRequestOptions = TransactionalBatchItemRequestOptions.FromItemRequestOptions(itemRequestOptions); ItemBatchOperation itemBatchOperation = new ItemBatchOperation( operationType: operationType, operationIndex: 0, partitionKey: partitionKey, id: itemId, resourceStream: streamPayload, requestOptions: batchItemRequestOptions, cosmosClientContext: this); TransactionalBatchOperationResult batchOperationResult = await cosmosContainerCore.BatchExecutor.AddAsync( itemBatchOperation, itemRequestOptions, cancellationToken); return(batchOperationResult.ToResponseMessage()); }
public void GenericCanBeMocked() { Mock <TransactionalBatchOperationResult <object> > mockResult = new Mock <TransactionalBatchOperationResult <object> >(); TransactionalBatchOperationResult <object> result = mockResult.Object; Assert.AreEqual(default(HttpStatusCode), result.StatusCode); Assert.AreEqual(default(object), result.Resource); }
public void IsSuccessStatusCodeTrueFor200to299() { for (int x = 100; x < 999; ++x) { TransactionalBatchOperationResult result = new TransactionalBatchOperationResult((HttpStatusCode)x); bool success = x >= 200 && x <= 299; Assert.AreEqual(success, result.IsSuccessStatusCode); } }
internal TransactionalBatchOperationResult(TransactionalBatchOperationResult other) { this.StatusCode = other.StatusCode; this.SubStatusCode = other.SubStatusCode; this.ETag = other.ETag; this.ResourceStream = other.ResourceStream; this.RequestCharge = other.RequestCharge; this.RetryAfter = other.RetryAfter; }
public void Complete( BatchAsyncBatcher completer, TransactionalBatchOperationResult result) { if (this.AssertBatcher(completer)) { this.taskCompletionSource.SetResult(result); } this.Dispose(); }
public void PropertiesAreSetThroughCopyCtor() { TransactionalBatchOperationResult other = CreateTestResult(); TransactionalBatchOperationResult result = new TransactionalBatchOperationResult(other); Assert.AreEqual(other.StatusCode, result.StatusCode); Assert.AreEqual(other.SubStatusCode, result.SubStatusCode); Assert.AreEqual(other.ETag, result.ETag); Assert.AreEqual(other.RequestCharge, result.RequestCharge); Assert.AreEqual(other.RetryAfter, result.RetryAfter); Assert.AreSame(other.ResourceStream, result.ResourceStream); }
public void Complete( BatchAsyncBatcher completer, TransactionalBatchOperationResult result) { if (this.AssertBatcher(completer)) { this.initialTrace.AddChild(result.Trace); result.Trace = this.initialTrace; this.taskCompletionSource.SetResult(result); } this.Dispose(); }
public void ToResponseMessageHasPropertiesMapped() { TransactionalBatchOperationResult result = CreateTestResult(); ResponseMessage response = result.ToResponseMessage(); Assert.AreEqual(result.StatusCode, response.StatusCode); Assert.AreEqual(result.SubStatusCode, response.Headers.SubStatusCode); Assert.AreEqual(result.ETag, response.Headers.ETag); Assert.AreEqual(result.RequestCharge, response.Headers.RequestCharge); Assert.AreEqual(result.RetryAfter, response.Headers.RetryAfter); Assert.AreSame(result.ResourceStream, response.Content); Assert.AreSame(result.Diagnostics, response.Diagnostics); }
public void PropertiesAreSetThroughGenericCtor() { TransactionalBatchOperationResult other = CreateTestResult(); object testObject = new object(); TransactionalBatchOperationResult <object> result = new TransactionalBatchOperationResult <object>(other, testObject); Assert.AreEqual(other.StatusCode, result.StatusCode); Assert.AreEqual(other.SubStatusCode, result.SubStatusCode); Assert.AreEqual(other.ETag, result.ETag); Assert.AreEqual(other.RequestCharge, result.RequestCharge); Assert.AreEqual(other.RetryAfter, result.RetryAfter); Assert.AreSame(other.ResourceStream, result.ResourceStream); Assert.AreSame(testObject, result.Resource); }
/// <summary> /// Based on the Retry Policy, if a failed response should retry. /// </summary> public Task <ShouldRetryResult> ShouldRetryAsync( TransactionalBatchOperationResult batchOperationResult, CancellationToken cancellationToken) { if (this.retryPolicy == null || batchOperationResult.IsSuccessStatusCode) { return(Task.FromResult(ShouldRetryResult.NoRetry())); } ResponseMessage responseMessage = batchOperationResult.ToResponseMessage(); return(this.retryPolicy.ShouldRetryAsync(responseMessage, cancellationToken)); }
/// <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 TransactionalBatchOperationResult <T> GetOperationResultAtIndex <T>(int index) { if (index >= this.Count) { throw new IndexOutOfRangeException(); } TransactionalBatchOperationResult result = this.resultsByOperationIndex[index]; T resource = default; if (result.ResourceStream != null) { resource = this.SerializerCore.FromStream <T>(result.ResourceStream); } return(new TransactionalBatchOperationResult <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; TransactionalBatchItemRequestOptions batchItemRequestOptions = TransactionalBatchItemRequestOptions.FromItemRequestOptions(itemRequestOptions); ItemBatchOperation itemBatchOperation = new ItemBatchOperation(operationType, /* index */ 0, partitionKey, itemId, streamPayload, batchItemRequestOptions); TransactionalBatchOperationResult batchOperationResult = await cosmosContainerCore.BatchExecutor.AddAsync(itemBatchOperation, itemRequestOptions, cancellationToken); return(batchOperationResult.ToResponseMessage()); }
/// <summary> /// Based on the Retry Policy, if a failed response should retry. /// </summary> public async Task <ShouldRetryResult> ShouldRetryAsync( TransactionalBatchOperationResult batchOperationResult, CancellationToken cancellationToken) { if (this.retryPolicy == null || batchOperationResult.IsSuccessStatusCode) { return(ShouldRetryResult.NoRetry()); } ResponseMessage responseMessage = batchOperationResult.ToResponseMessage(); ShouldRetryResult shouldRetry = await this.retryPolicy.ShouldRetryAsync(responseMessage, cancellationToken); if (shouldRetry.ShouldRetry) { this.initialTrace.AddChild(batchOperationResult.Trace); } return(shouldRetry); }
public void StatusCodeIsSetThroughCtor() { TransactionalBatchOperationResult result = new TransactionalBatchOperationResult(HttpStatusCode.Unused); Assert.AreEqual(HttpStatusCode.Unused, result.StatusCode); }
private static Result ReadOperationResult(ref RowReader reader, out TransactionalBatchOperationResult batchOperationResult) { batchOperationResult = new TransactionalBatchOperationResult(); 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); }
public virtual async Task DispatchAsync( BatchPartitionMetric partitionMetric, CancellationToken cancellationToken = default) { 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 { Stopwatch stopwatch = Stopwatch.StartNew(); PartitionKeyRangeBatchExecutionResult result = await this.executor(serverRequest, cancellationToken); int numThrottle = result.ServerResponse.Any(r => r.StatusCode == (System.Net.HttpStatusCode)StatusCodes.TooManyRequests) ? 1 : 0; partitionMetric.Add( numberOfDocumentsOperatedOn: result.ServerResponse.Count, timeTakenInMilliseconds: stopwatch.ElapsedMilliseconds, numberOfThrottles: numThrottle); using (PartitionKeyRangeBatchResponse batchResponse = new PartitionKeyRangeBatchResponse(serverRequest.Operations.Count, result.ServerResponse, this.serializerCore)) { foreach (ItemBatchOperation itemBatchOperation in batchResponse.Operations) { TransactionalBatchOperationResult response = batchResponse[itemBatchOperation.OperationIndex]; // Bulk has diagnostics per a item operation. // Batch has a single diagnostics for the execute operation if (itemBatchOperation.DiagnosticsContext != null) { response.DiagnosticsContext = itemBatchOperation.DiagnosticsContext; response.DiagnosticsContext.AddDiagnosticsInternal(batchResponse.DiagnosticsContext); } else { response.DiagnosticsContext = batchResponse.DiagnosticsContext; } if (!response.IsSuccessStatusCode) { Documents.ShouldRetryResult shouldRetry = await itemBatchOperation.Context.ShouldRetryAsync(response, cancellationToken); if (shouldRetry.ShouldRetry) { await this.retrier(itemBatchOperation, cancellationToken); continue; } } 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.dispatched = true; } }
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); using (PartitionKeyRangeBatchResponse batchResponse = new PartitionKeyRangeBatchResponse(serverRequest.Operations.Count, result.ServerResponse, this.serializerCore)) { foreach (ItemBatchOperation itemBatchOperation in batchResponse.Operations) { TransactionalBatchOperationResult response = batchResponse[itemBatchOperation.OperationIndex]; itemBatchOperation.Context.Diagnostics.AppendDiagnostics(batchResponse.Diagnostics); if (!response.IsSuccessStatusCode) { Documents.ShouldRetryResult shouldRetry = await itemBatchOperation.Context.ShouldRetryAsync(response, cancellationToken); if (shouldRetry.ShouldRetry) { await this.retrier(itemBatchOperation, cancellationToken); continue; } } 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; } }