Esempio n. 1
0
        private async Task ExecuteOperationAsync(GraphQLOperation op, OutputObjectScope topScope)
        {
            var opOutItemSet = op.SelectionSubset.MappedItemSets.FirstOrDefault(fi => fi.ObjectTypeDef == op.OperationTypeDef);
            var topFields    = _requestContext.GetIncludedMappedFields(opOutItemSet);

            topScope.Init(op.OperationTypeDef, topFields);
            var parallel = _parallelQuery && op.OperationType == OperationType.Query && topFields.Count > 1;

            // Note: if we go parallel here, note that the topScope is safe for concurrent thread access;
            //   it is only used to save op result value (SetValue method)
            var executers = new List <OperationFieldExecuter>();

            for (int fieldIndex = 0; fieldIndex < topFields.Count; fieldIndex++)
            {
                var opExecuter = new OperationFieldExecuter(_requestContext, topScope, fieldIndex);
                executers.Add(opExecuter);
            }

            _requestContext.Metrics.ExecutionThreadCount = executers.Count;
            if (parallel)
            {
                await ExecuteAllParallel(executers);
            }
            else
            {
                await ExecuteAllNonParallel(executers);
            }
        }
Esempio n. 2
0
        public object CreateObjectFieldResultScope(object entity, RequestPath path)
        {
            // special case - Union
            if (TypeDef.Kind == TypeKind.Union)
            {
                if (entity is UnionBase ub)
                {
                    entity = ub.Value;
                }
                if (entity == null)
                {
                    return(null);
                }
            }
            var entType = entity.GetType();
            var mapping = TypeDef.FindMapping(entType);

            if (mapping == null)
            {
                throw new FatalServerException($"FATAL: failed to find mapping for entity type {entType} in the type {TypeDef.Name}. ");
            }
            var scope = new OutputObjectScope(path, entity, mapping);

            AllResultScopes.Add(scope);
            var newCount = Interlocked.Increment(ref _requestContext.Metrics.OutputObjectCount);

            // check total count against quota
            if (newCount > _requestContext.Quota.MaxOutputObjects)
            {
                this.ThrowObjectCountExceededQuota();
            }
            return(scope);
        }
Esempio n. 3
0
        public async Task ExecuteAsync()
        {
            if (!ParseBuildRequest())
            {
                return;
            }
            AssignRequestOperation();
            if (_requestContext.Failed)
            {
                return;
            }

            // signal to prepare/deserialize variables; in http/web scenario, we cannot parse variables immediately -
            // we do not know variable types yet. Now that we have parsed and prepared query, we have var types;
            // we fire this event, parent GraphQLHttpServer will handle it and deserializer variables.
            _server.Events.OnRequestPrepared(_requestContext);
            BuildOperationVariables();
            if (_requestContext.Failed)
            {
                return;
            }

            var topScope = new OutputObjectScope(); // we do not count it as an 'output object', so no incr of object count in metrics

            _requestContext.Response.Data = topScope;
            await ExecuteOperationAsync(_requestContext.Operation, topScope);
        }
 public OperationFieldExecuter(RequestContext requestContext, OutputObjectScope parentScope, int fieldIndex)
 {
     _requestContext = requestContext;
     _parentScope    = parentScope;
     _fieldIndex     = fieldIndex;
     _operationField = _parentScope.Fields[_fieldIndex];
 }
Esempio n. 5
0
        public object CreateObjectFieldResultScopes(object rawResult, int rank, RequestPath path)
        {
            if (rawResult == null)
            {
                return(null);
            }

            // check field depth against quota
            if (path.FieldDepth > _requestContext.Quota.MaxDepth)
            {
                this.ThrowFieldDepthExceededQuota();
            }

            switch (rank)
            {
            case 0:
                var typeDef = Field.FieldDef.TypeRef.TypeDef;
                // special cases - Union, Interface; extract actual value from box
                switch (typeDef.Kind)
                {
                case TypeKind.Union:
                    if (rawResult is UnionBase ub)
                    {
                        rawResult = ub.Value;
                    }
                    if (rawResult == null)
                    {
                        return(null);
                    }
                    break;

                case TypeKind.Interface:
                    if (rawResult == null)
                    {
                        return(null);
                    }
                    break;
                }
                var scope = new OutputObjectScope(this, path, rawResult);
                AllResultScopes.Add(scope);
                var newCount = Interlocked.Increment(ref _requestContext.Metrics.OutputObjectCount);
                // check total count against quota
                if (newCount > _requestContext.Quota.MaxOutputObjects)
                {
                    this.ThrowObjectCountExceededQuota();
                }
                return(scope);

            default: // rank > 0, array
                var list   = rawResult as IList;
                var scopes = new object[list.Count];
                for (int i = 0; i < list.Count; i++)
                {
                    scopes[i] = CreateObjectFieldResultScopes(list[i], rank - 1, path.Append(i));
                }
                return(scopes);
            }
        }
        private ObjectTypeDef GetMappedObjectTypeDef(OutputObjectScope scope)
        {
            object entity  = scope.Entity;
            var    typeDef = _requestContext.ApiModel.GetMappedGraphQLType(entity.GetType());

            if (typeDef == null || typeDef.Kind != TypeKind.Object)
            {
                // TODO: see if it can happen we can throw better error here
            }
            return((ObjectTypeDef)typeDef);
        }
Esempio n. 7
0
 internal void SetCurrentParentScope(OutputObjectScope scope)
 {
     _currentParentScope = scope;
 }
 public OperationFieldExecuter(RequestContext requestContext, MappedSelectionField mappedOpField, OutputObjectScope parentScope)
 {
     _requestContext = requestContext;
     _parentScope    = parentScope;
     _mappedOpField  = mappedOpField;
 }