示例#1
0
        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);
            }
        }
示例#2
0
        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);
        }
示例#3
0
        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();
            }
        }
示例#10
0
        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();
            }
        }
示例#12
0
        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);
        }
示例#13
0
 protected static Task CompleteBatchOperationsAsync(
     IReadOnlyCollection <Task> tasks,
     BatchOperationHandler batchOperationHandler,
     CancellationToken cancellationToken)
 {
     return((batchOperationHandler == null)
         ? Task.CompletedTask
         : batchOperationHandler.CompleteAsync(
                tasks, cancellationToken));
 }
示例#14
0
        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);
        }
示例#16
0
        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();
            }
        }
示例#17
0
        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();
            }
        }