public ResolverTask( IExecutionContext executionContext, ObjectType objectType, FieldSelection fieldSelection, Path path, ImmutableStack <object> source, OrderedDictionary result) { _executionContext = executionContext; Source = source; ObjectType = objectType; FieldSelection = fieldSelection; FieldType = fieldSelection.Field.Type; Path = path; Result = result; ResolverContext = new ResolverContext( executionContext, this, executionContext.CancellationToken); Options = executionContext.Options; ExecuteMiddleware = executionContext.GetMiddleware( objectType, fieldSelection.Selection); HasMiddleware = ExecuteMiddleware != null; }
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); }
private async Task ExecuteFieldResolverBatchAsync( ExecutionContext executionContext, List <FieldResolverTask> batch, CancellationToken cancellationToken) { List <(FieldResolverTask task, IResolverContext context, object resolverResult)> runningTasks = new List <(FieldResolverTask, IResolverContext, object)>(); foreach (FieldResolverTask task in batch) { IResolverContext resolverContext = new ResolverContext( executionContext, task); object resolverResult = task.FieldSelection.Field.Resolver( resolverContext, cancellationToken); runningTasks.Add((task, resolverContext, resolverResult)); } foreach (var runningTask in runningTasks) { FieldSelection fieldSelection = runningTask.task.FieldSelection; object fieldValue = await CompleteFieldValueAsync( runningTask.resolverResult); TryCompleteValue(executionContext, runningTask.context, runningTask.task.Source, fieldSelection, fieldSelection.Field.Type, runningTask.task.Path, fieldValue, runningTask.task.SetValue); cancellationToken.ThrowIfCancellationRequested(); } }
private async Task ExecuteFieldResolverBatchSeriallyAsync( ExecutionContext executionContext, List <FieldResolverTask> batch, CancellationToken cancellationToken) { List <(FieldResolverTask task, object resolverResult)> runningTasks = new List <(FieldResolverTask, object)>(); foreach (FieldResolverTask task in batch) { // execute resolver IResolverContext resolverContext = new ResolverContext( executionContext, task); object resolverResult = task.FieldSelection.Field.Resolver( resolverContext, cancellationToken); // complete resolver value FieldSelection fieldSelection = task.FieldSelection; object fieldValue = await CompleteFieldValueAsync( resolverResult); TryCompleteValue(executionContext, resolverContext, task.Source, fieldSelection, fieldSelection.Field.Type, task.Path, fieldValue, task.SetValue); // execute sub-selection fields normally await ExecuteFieldResolversAsync(executionContext, cancellationToken); cancellationToken.ThrowIfCancellationRequested(); } }
protected static ResolverContext[] CreateInitialBatch( IExecutionContext executionContext, IDictionary <string, object> result) { ImmutableStack <object> source = ImmutableStack <object> .Empty .Push(executionContext.Operation.RootValue); IReadOnlyCollection <FieldSelection> fieldSelections = executionContext.CollectFields( executionContext.Operation.RootType, executionContext.Operation.Definition.SelectionSet, null); int i = 0; ResolverContext[] batch = ArrayPool <ResolverContext> .Shared.Rent( fieldSelections.Count); foreach (FieldSelection fieldSelection in fieldSelections) { batch[i++] = ResolverContext.Rent( executionContext, fieldSelection, source, result); } return(batch); }
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); } }
public static void CompleteValue( this CompleteValueContext completionContext, ResolverContext resolverContext) { if (completionContext == null) { throw new ArgumentNullException(nameof(completionContext)); } completionContext.ResolverContext = resolverContext; ValueCompletion.CompleteValue( completionContext, resolverContext.Field.Type, resolverContext.Result); if (completionContext.IsViolatingNonNullType) { resolverContext.PropagateNonNullViolation.Invoke(); } else { resolverContext.SetCompletedValue(completionContext.Value); } }
private async Task ExecuteFieldResolverBatchSeriallyAsync( ExecutionContext executionContext, List <FieldResolverTask> batch, CancellationToken cancellationToken) { List <(FieldResolverTask task, object resolverResult)> runningTasks = new List <(FieldResolverTask, object)>(); foreach (FieldResolverTask task in batch) { // execute resolver ResolverContext resolverContext = new ResolverContext( executionContext, task); object resolverResult = ExecuteFieldResolver( resolverContext, task.FieldSelection.Field, task.FieldSelection.Node, cancellationToken); // handle async results resolverResult = await HandleFieldValueAsync( resolverResult); FieldValueCompletionContext completionContext = new FieldValueCompletionContext( executionContext, resolverContext, task.FieldSelection, task.SetValue, resolverResult); CompleteValue(completionContext); // execute sub-selection fields normally await ExecuteFieldResolversAsync(executionContext, cancellationToken); cancellationToken.ThrowIfCancellationRequested(); } }
private ResolverTask( ResolverTask parent, FieldSelection fieldSelection, Path path, IImmutableStack <object> source, IDictionary <string, object> result, Action propagateNonNullViolation) { _parent = parent; _executionContext = parent._executionContext; Source = source; ObjectType = fieldSelection.Field.DeclaringType; FieldSelection = fieldSelection; FieldType = fieldSelection.Field.Type; Path = path; _result = result; ScopedContextData = parent.ScopedContextData; _propagateNonNullViolation = propagateNonNullViolation; ResolverContext = new ResolverContext( parent._executionContext, this, parent._executionContext.RequestAborted); FieldDelegate = parent._executionContext.FieldHelper .CreateMiddleware(fieldSelection); }
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); } }
public static void CompleteValue( Action <ResolverContext> enqueueNext, ResolverContext resolverContext) { CompleteValueContext completionContext = _completionContext.Value; completionContext.Clear(); completionContext.EnqueueNext = enqueueNext; completionContext.ResolverContext = resolverContext; CompleteValue( completionContext, resolverContext.Field.Type, resolverContext.Result); if (completionContext.IsViolatingNonNullType) { resolverContext.PropagateNonNullViolation.Invoke(); } else { resolverContext.SetCompletedValue(completionContext.Value); } completionContext.Clear(); }
public void Clear() { _resolverContext = null; _selection = null; _selectionSet = null; _path = null; EnqueueNext = null; Value = null; HasErrors = false; IsViolatingNonNullType = false; SetElementNull = null; }
public static ResolverContext Rent( IExecutionContext executionContext, FieldSelection fieldSelection, IImmutableStack <object> source, IDictionary <string, object> serializedResult) { var context = new ResolverContext(); context.Initialize( executionContext, fieldSelection, source, serializedResult); return(context); }
public ResolverTask( IExecutionContext executionContext, ObjectType objectType, FieldSelection fieldSelection, Path path, ImmutableStack <object> source, OrderedDictionary result) { Source = source; ObjectType = objectType; FieldSelection = fieldSelection; FieldType = fieldSelection.Field.Type; Path = path; Result = result; ResolverContext = new ResolverContext(executionContext, this); }
private async Task <IExecutionResult> ExecuteInternalAsync( IExecutionContext executionContext) { object rootValue = executionContext.Operation.RootValue; FieldSelection fieldSelection = executionContext.CollectFields( executionContext.Schema.SubscriptionType, executionContext.Operation.Definition.SelectionSet, null) .Single(); ImmutableStack <object> source = ImmutableStack.Create(rootValue); var subscribeContext = ResolverContext.Rent( executionContext, fieldSelection, source, new FieldData(1)); SubscribeResolverDelegate subscribeResolver = fieldSelection.Field.SubscribeResolver ?? DefaultSubscribeResolverAsync; try { IAsyncEnumerable <object> sourceStream = await subscribeResolver(subscribeContext) .ConfigureAwait(false); return(new SubscriptionResult( sourceStream, message => { IExecutionContext cloned = executionContext.Clone(); cloned.ContextData[WellKnownContextData.EventMessage] = message; return cloned; }, ExecuteSubscriptionQueryAsync, executionContext.ServiceScope, executionContext.RequestAborted)); } finally { ResolverContext.Return(subscribeContext); } }
private async Task ExecuteFieldResolverBatchAsync( ExecutionContext executionContext, List <FieldResolverTask> batch, CancellationToken cancellationToken) { List <(FieldResolverTask task, IResolverContext context, object resolverResult)> runningTasks = new List <(FieldResolverTask, IResolverContext, object)>(); foreach (FieldResolverTask task in batch) { IResolverContext resolverContext = new ResolverContext( executionContext, task); if (task.Path.Depth <= _maxExecutionDepth) { object resolverResult = ExecuteFieldResolver( resolverContext, task.FieldSelection.Field, task.FieldSelection.Node, cancellationToken); runningTasks.Add((task, resolverContext, resolverResult)); } else { runningTasks.Add((task, resolverContext, new FieldError( $"The field has a depth of {task.Path.Depth}, " + "which exceeds max allowed depth of " + $"{_maxExecutionDepth}", task.FieldSelection.Node))); } } foreach (var runningTask in runningTasks) { object fieldValue = await HandleFieldValueAsync( runningTask.resolverResult); FieldValueCompletionContext completionContext = new FieldValueCompletionContext( executionContext, runningTask.context, runningTask.task.FieldSelection, runningTask.task.SetValue, fieldValue); CompleteValue(completionContext); cancellationToken.ThrowIfCancellationRequested(); } }
private void Initialize( FieldSelection fieldSelection, IImmutableStack <object> source, object sourceObject, ResolverContext sourceContext, FieldData serializedResult, Path path, Action propagateNonNullViolation) { _executionContext = sourceContext._executionContext; _serializedResult = serializedResult; _fieldSelection = fieldSelection; _arguments = fieldSelection.CoerceArguments( sourceContext._executionContext.Variables, sourceContext._executionContext.Converter); Path = path; Source = source; SourceObject = sourceObject; ScopedContextData = sourceContext.ScopedContextData; LocalContextData = ImmutableDictionary <string, object> .Empty; bool isNonNullType = fieldSelection.Field.Type.IsNonNullType(); Action parentPropagateNonNullViolation = sourceContext.PropagateNonNullViolation; PropagateNonNullViolation = () => { if (isNonNullType) { if (propagateNonNullViolation != null) { propagateNonNullViolation.Invoke(); } else if (parentPropagateNonNullViolation != null) { parentPropagateNonNullViolation.Invoke(); } } serializedResult.SetFieldValue( fieldSelection.ResponseIndex, fieldSelection.ResponseName, null); }; }
public ResolverContext Branch( FieldSelection fieldSelection, IImmutableStack <object> source, object sourceObject, IDictionary <string, object> serializedResult, Path path, Action propagateNonNullViolation) { ResolverContext branch = Rent( fieldSelection, source, sourceObject, this, serializedResult, path, propagateNonNullViolation); return(branch); }
private void Initialize( FieldSelection fieldSelection, IImmutableStack <object> source, object sourceObject, ResolverContext sourceContext, IDictionary <string, object> serializedResult, Path path, Action propagateNonNullViolation) { _executionContext = sourceContext._executionContext; _serializedResult = serializedResult; _fieldSelection = fieldSelection; _arguments = fieldSelection.CoerceArguments( sourceContext._executionContext.Variables); Path = path; Source = source; SourceObject = sourceObject; ScopedContextData = sourceContext.ScopedContextData; bool isNonNullType = fieldSelection.Field.Type.IsNonNullType(); string responseName = fieldSelection.ResponseName; Action parentPropagateNonNullViolation = sourceContext.PropagateNonNullViolation; PropagateNonNullViolation = () => { if (isNonNullType) { if (propagateNonNullViolation != null) { propagateNonNullViolation.Invoke(); } else if (parentPropagateNonNullViolation != null) { parentPropagateNonNullViolation.Invoke(); } } serializedResult[responseName] = null; }; }
protected static async Task ExecuteResolverAsync( ResolverContext resolverContext, IErrorHandler errorHandler) { Activity activity = resolverContext.BeginResolveField(); await ExecuteMiddlewareAsync(resolverContext, errorHandler) .ConfigureAwait(false); if (resolverContext.Result is IError singleError) { resolverContext.ResolverError(singleError); } else if (resolverContext.Result is IEnumerable <IError> errors) { resolverContext.ResolverError(errors); } resolverContext.EndResolveField(activity); }
private static async Task EndExecuteResolverBatchAsync( IEnumerable <ResolverContext> batch, Action <ResolverContext> enqueueNext, CancellationToken cancellationToken) { foreach (ResolverContext resolverContext in batch) { if (resolverContext.Task.Status != TaskStatus.RanToCompletion) { await resolverContext.Task.ConfigureAwait(false); } ValueCompletion.CompleteValue(enqueueNext, resolverContext); if (!resolverContext.IsRoot) { ResolverContext.Return(resolverContext); } } }
private static async Task ExecuteMiddlewareAsync( ResolverContext resolverContext, IErrorHandler errorHandler) { try { await resolverContext.Middleware.Invoke(resolverContext) .ConfigureAwait(false); } catch (QueryException ex) { resolverContext.Result = ex.Errors; } catch (Exception ex) { resolverContext.Result = errorHandler.CreateUnexpectedError(ex) .SetPath(resolverContext.Path) .AddLocation(resolverContext.FieldSelection) .Build(); } }
private static ResolverContext Rent( FieldSelection fieldSelection, IImmutableStack <object> source, object sourceObject, ResolverContext sourceContext, IDictionary <string, object> serializedResult, Path path, Action propagateNonNullViolation) { // var context = ObjectPools.ResolverContexts.Rent(); var context = new ResolverContext(); context.Initialize( fieldSelection, source, sourceObject, sourceContext, serializedResult, path, propagateNonNullViolation); return(context); }
public ResolverTask( IExecutionContext executionContext, FieldSelection fieldSelection, IImmutableStack <object> source, IDictionary <string, object> result) { _executionContext = executionContext; Source = source; ObjectType = fieldSelection.Field.DeclaringType; FieldSelection = fieldSelection; FieldType = fieldSelection.Field.Type; Path = Path.New(fieldSelection.ResponseName); _result = result; ScopedContextData = ImmutableDictionary <string, object> .Empty; ResolverContext = new ResolverContext( executionContext, this, executionContext.RequestAborted); FieldDelegate = executionContext.FieldHelper .CreateMiddleware(fieldSelection); }
private static async Task ExecuteMiddlewareAsync( ResolverContext resolverContext, IErrorHandler errorHandler) { try { await resolverContext.Middleware.Invoke(resolverContext) .ConfigureAwait(false); // TODO : this should be handled more elegant if (resolverContext.Result is IQueryable q) { resolverContext.Result = await Task.Run(() => { var items = new List <object>(); foreach (object o in q) { items.Add(o); } return(items); }) .ConfigureAwait(false); } } catch (GraphQLException ex) { resolverContext.Result = ex.Errors; } catch (Exception ex) { resolverContext.Result = errorHandler.CreateUnexpectedError(ex) .SetPath(resolverContext.Path) .AddLocation(resolverContext.FieldSelection) .Build(); } }
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(); } }
public ResolverTask( IExecutionContext executionContext, ObjectType objectType, FieldSelection fieldSelection, Path path, IImmutableStack <object> source, IDictionary <string, object> result) { _executionContext = executionContext; Source = source; ObjectType = objectType; FieldSelection = fieldSelection; FieldType = fieldSelection.Field.Type; Path = path; _result = result; ResolverContext = new ResolverContext( executionContext, this, executionContext.RequestAborted); ExecuteMiddleware = executionContext.FieldHelper.CreateMiddleware( objectType, fieldSelection.Selection); HasMiddleware = ExecuteMiddleware != null; }
public static void Return(ResolverContext rentedContext) { //ObjectPools.ResolverContexts.Return(rentedContext); }