private async Task <IExecutionResult> ExecuteMutationAsync( IExecutionContext executionContext, CancellationToken cancellationToken) { ResolverContext[] initialBatch = CreateInitialBatch(executionContext, executionContext.Result.Data); BatchOperationHandler batchOperationHandler = CreateBatchOperationHandler(executionContext); try { await ExecuteResolverBatchSeriallyAsync( executionContext, initialBatch, batchOperationHandler, cancellationToken) .ConfigureAwait(false); EnsureRootValueNonNullState( executionContext.Result, initialBatch); return(executionContext.Result); } finally { batchOperationHandler?.Dispose(); ResolverContext.Return(initialBatch); ArrayPool <ResolverContext> .Shared.Return(initialBatch); } }
private static async Task ExecuteResolverBatchAsync( IExecutionContext executionContext, IReadOnlyCollection <ResolverTask> currentBatch, ICollection <ResolverTask> nextBatch, BatchOperationHandler batchOperationHandler, CancellationToken cancellationToken) { // start field resolvers IReadOnlyCollection <Task> tasks = BeginExecuteResolverBatch( currentBatch, executionContext.ErrorHandler, cancellationToken); // execute batch data loaders await CompleteBatchOperationsAsync( tasks, batchOperationHandler, cancellationToken) .ConfigureAwait(false); // await field resolver results await EndExecuteResolverBatchAsync( executionContext, currentBatch, nextBatch.Add, cancellationToken) .ConfigureAwait(false); }
protected static async Task <IReadOnlyQueryResult> ExecuteQueryAsync( IExecutionContext executionContext, BatchOperationHandler batchOperationHandler, CancellationToken cancellationToken) { InitialBatch initialBatch = CreateInitialBatch(executionContext); try { await ExecuteResolversAsync( executionContext, initialBatch.Batch, batchOperationHandler, cancellationToken) .ConfigureAwait(false); FieldData data = EnsureRootValueNonNullState( initialBatch.Data, initialBatch.Batch); if (data is { }) { executionContext.Result.SetData(initialBatch.Data); } return(executionContext.Result.Create()); }
private static async Task <IExecutionResult> ExecuteMutationAsync( IExecutionContext executionContext, CancellationToken cancellationToken) { InitialBatch initialBatch = CreateInitialBatch(executionContext); BatchOperationHandler batchOperationHandler = CreateBatchOperationHandler(executionContext); try { await ExecuteResolverBatchSeriallyAsync( executionContext, initialBatch.Batch, batchOperationHandler, cancellationToken) .ConfigureAwait(false); FieldData data = EnsureRootValueNonNullState( initialBatch.Data, initialBatch.Batch); if (data is { }) { executionContext.Result.SetData(data); } return(executionContext.Result.Create()); }
protected static async Task <IQueryResult> ExecuteQueryAsync( IExecutionContext executionContext, BatchOperationHandler batchOperationHandler, CancellationToken cancellationToken) { ResolverContext[] initialBatch = CreateInitialBatch(executionContext, executionContext.Result.Data); try { await ExecuteResolversAsync( executionContext, initialBatch, batchOperationHandler, cancellationToken) .ConfigureAwait(false); EnsureRootValueNonNullState( executionContext.Result, initialBatch); return(executionContext.Result); } finally { ResolverContext.Return(initialBatch); ArrayPool <ResolverContext> .Shared.Return(initialBatch); } }
private async Task ExecuteResolverSeriallyAsync( IExecutionContext executionContext, ResolverTask resolverTask, Action <ResolverTask> enqueueTask, BatchOperationHandler batchOperationHandler, CancellationToken cancellationToken) { resolverTask.Task = ExecuteResolverAsync( resolverTask, executionContext.ErrorHandler, cancellationToken); await CompleteBatchOperationsAsync( new[] { resolverTask.Task }, batchOperationHandler, cancellationToken) .ConfigureAwait(false); resolverTask.ResolverResult = await resolverTask.Task .ConfigureAwait(false); // serialize and integrate result into final query result var completionContext = new CompleteValueContext( executionContext.Services.GetTypeConversion(), executionContext.FieldHelper, enqueueTask); completionContext.CompleteValue(resolverTask); }
protected static async Task CompleteBatchOperationsAsync( IReadOnlyList <ResolverContext> batch, BatchOperationHandler batchOperationHandler, CancellationToken cancellationToken) { Debug.Assert(batch != null); Debug.Assert(batchOperationHandler != null); Task[] tasks = ArrayPool <Task> .Shared.Rent(batch.Count); for (int i = 0; i < batch.Count; i++) { tasks[i] = batch[i].Task; } var taskMemory = new Memory <Task>(tasks); taskMemory = taskMemory.Slice(0, batch.Count); try { await batchOperationHandler.CompleteAsync( taskMemory, cancellationToken) .ConfigureAwait(false); } finally { ArrayPool <Task> .Shared.Return(tasks); } }
private async Task <IExecutionResult> ExecuteMutationAsync( IExecutionContext executionContext, CancellationToken cancellationToken) { BatchOperationHandler batchOperationHandler = CreateBatchOperationHandler(executionContext); try { IReadOnlyList <ResolverTask> rootResolverTasks = CreateRootResolverTasks( executionContext, executionContext.Result.Data); await ExecuteResolverBatchSeriallyAsync( executionContext, rootResolverTasks, batchOperationHandler, cancellationToken) .ConfigureAwait(false); EnsureRootValueNonNullState( executionContext.Result, rootResolverTasks); return(executionContext.Result); } finally { batchOperationHandler?.Dispose(); } }
private async Task ExecuteResolverBatchSeriallyAsync( IExecutionContext executionContext, IEnumerable <ResolverTask> currentBatch, BatchOperationHandler batchOperationHandler, CancellationToken cancellationToken) { var nextBatch = new List <ResolverTask>(); foreach (ResolverTask resolverTask in currentBatch) { await ExecuteResolverSeriallyAsync( executionContext, resolverTask, nextBatch.Add, batchOperationHandler, cancellationToken) .ConfigureAwait(false); // execute child fields with the default parallel flow logic await ExecuteResolversAsync( executionContext, nextBatch, batchOperationHandler, cancellationToken) .ConfigureAwait(false); nextBatch.Clear(); cancellationToken.ThrowIfCancellationRequested(); } }
protected static async Task ExecuteResolversAsync( IExecutionContext executionContext, IEnumerable <ResolverTask> initialBatch, BatchOperationHandler batchOperationHandler, CancellationToken cancellationToken) { var currentBatch = new List <ResolverTask>(initialBatch); var nextBatch = new List <ResolverTask>(); List <ResolverTask> swap = null; while (currentBatch.Count > 0) { await ExecuteResolverBatchAsync( executionContext, currentBatch, nextBatch, batchOperationHandler, cancellationToken) .ConfigureAwait(false); swap = currentBatch; currentBatch = nextBatch; nextBatch = swap; nextBatch.Clear(); cancellationToken.ThrowIfCancellationRequested(); } }
private async Task <IReadOnlyQueryResult> ExecuteSubscriptionQueryAsync( IExecutionContext executionContext, CancellationToken cancellationToken) { BatchOperationHandler batchOperationHandler = CreateBatchOperationHandler(executionContext); var requestTimeoutCts = new CancellationTokenSource( _options.ExecutionTimeout); try { using (var combinedCts = CancellationTokenSource .CreateLinkedTokenSource( requestTimeoutCts.Token, cancellationToken)) { IQueryResult result = await ExecuteQueryAsync( executionContext, batchOperationHandler, cancellationToken) .ConfigureAwait(false); return(result.AsReadOnly()); } } finally { batchOperationHandler?.Dispose(); requestTimeoutCts.Dispose(); } }
private static async Task ExecuteResolverSeriallyAsync( ResolverContext resolverContext, Action <ResolverContext> enqueueNext, BatchOperationHandler batchOperationHandler, IErrorHandler errorHandler, CancellationToken cancellationToken) { resolverContext.Task = ExecuteResolverAsync( resolverContext, errorHandler); if (batchOperationHandler != null) { await CompleteBatchOperationsAsync( new[] { resolverContext }, batchOperationHandler, cancellationToken) .ConfigureAwait(false); } await resolverContext.Task.ConfigureAwait(false); // serialize and integrate result into final query result var completionContext = new CompleteValueContext(enqueueNext); completionContext.CompleteValue(resolverContext); }
protected static Task CompleteBatchOperationsAsync( IReadOnlyCollection <Task> tasks, BatchOperationHandler batchOperationHandler, CancellationToken cancellationToken) { return((batchOperationHandler == null) ? Task.CompletedTask : batchOperationHandler.CompleteAsync( tasks, cancellationToken)); }
protected static async Task ExecuteResolversAsync( IExecutionContext executionContext, IEnumerable <ResolverContext> initialBatch, BatchOperationHandler batchOperationHandler, CancellationToken cancellationToken) { var batch = new List <ResolverContext>(); var next = new List <ResolverContext>(); List <ResolverContext> swap = null; foreach (ResolverContext resolverContext in initialBatch) { if (resolverContext == null) { break; } batch.Add(resolverContext); } while (batch.Count > 0) { // start field resolvers BeginExecuteResolverBatch( batch, executionContext.ErrorHandler, cancellationToken); // execute batch data loaders if (batchOperationHandler != null) { await CompleteBatchOperationsAsync( batch, batchOperationHandler, cancellationToken) .ConfigureAwait(false); } // await field resolver results await EndExecuteResolverBatchAsync( batch, next.Add, cancellationToken) .ConfigureAwait(false); swap = batch; batch = next; next = swap; next.Clear(); cancellationToken.ThrowIfCancellationRequested(); } }
protected async Task <IQueryResult> ExecuteQueryAsync( IExecutionContext executionContext, BatchOperationHandler batchOperationHandler, CancellationToken cancellationToken) { IEnumerable <ResolverTask> rootResolverTasks = CreateRootResolverTasks(executionContext, executionContext.Result.Data); await ExecuteResolversAsync( executionContext, rootResolverTasks, batchOperationHandler, cancellationToken) .ConfigureAwait(false); return(executionContext.Result); }
private static async Task <IExecutionResult> ExecuteInternalAsync( IExecutionContext executionContext, CancellationToken cancellationToken) { BatchOperationHandler batchOperationHandler = CreateBatchOperationHandler(executionContext); try { return(await ExecuteQueryAsync( executionContext, batchOperationHandler, cancellationToken) .ConfigureAwait(false)); } finally { batchOperationHandler?.Dispose(); } }
private static async Task ExecuteResolverBatchSeriallyAsync( IExecutionContext executionContext, IEnumerable <ResolverContext> batch, BatchOperationHandler batchOperationHandler, CancellationToken cancellationToken) { var next = new List <ResolverContext>(); foreach (ResolverContext resolverContext in batch) { if (resolverContext is null) { break; } await ExecuteResolverSeriallyAsync( resolverContext, next.Add, batchOperationHandler, executionContext.ErrorHandler, cancellationToken) .ConfigureAwait(false); cancellationToken.ThrowIfCancellationRequested(); // execute child fields with the default parallel flow logic await ExecuteResolversAsync( executionContext, next, batchOperationHandler, cancellationToken) .ConfigureAwait(false); ResolverContext.Return(next); next.Clear(); } }