public virtual async Task DispatchAsync( BatchPartitionMetric partitionMetric, CancellationToken cancellationToken = default) { using (ITrace trace = Tracing.Trace.GetRootTrace("Batch Dispatch Async", TraceComponent.Batch, Tracing.TraceLevel.Info)) { await this.DispatchHelperAsync(trace, partitionMetric, cancellationToken); } }
public virtual async Task DispatchAsync( BatchPartitionMetric partitionMetric, CancellationToken cancellationToken = default) { await this.clientContext.OperationHelperAsync("Batch Dispatch Async", requestOptions : null, task : (trace) => this.DispatchHelperAsync(trace, partitionMetric, cancellationToken), traceComponent : TraceComponent.Batch, traceLevel : Tracing.TraceLevel.Info); }
public BatchAsyncStreamer( int maxBatchOperationCount, int maxBatchByteSize, TimerWheel timerWheel, SemaphoreSlim limiter, int maxDegreeOfConcurrency, CosmosSerializerCore serializerCore, BatchAsyncBatcherExecuteDelegate executor, BatchAsyncBatcherRetryDelegate retrier) { if (maxBatchOperationCount < 1) { throw new ArgumentOutOfRangeException(nameof(maxBatchOperationCount)); } if (maxBatchByteSize < 1) { throw new ArgumentOutOfRangeException(nameof(maxBatchByteSize)); } if (executor == null) { throw new ArgumentNullException(nameof(executor)); } if (retrier == null) { throw new ArgumentNullException(nameof(retrier)); } if (serializerCore == null) { throw new ArgumentNullException(nameof(serializerCore)); } if (limiter == null) { throw new ArgumentNullException(nameof(limiter)); } if (maxDegreeOfConcurrency < 1) { throw new ArgumentNullException(nameof(maxDegreeOfConcurrency)); } this.maxBatchOperationCount = maxBatchOperationCount; this.maxBatchByteSize = maxBatchByteSize; this.executor = executor; this.retrier = retrier; this.timerWheel = timerWheel; this.serializerCore = serializerCore; this.currentBatcher = this.CreateBatchAsyncBatcher(); this.ResetTimer(); this.limiter = limiter; this.oldPartitionMetric = new BatchPartitionMetric(); this.partitionMetric = new BatchPartitionMetric(); this.maxDegreeOfConcurrency = maxDegreeOfConcurrency; this.StartCongestionControlTimer(); }
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; } }