MCPcopy Index your code
hub / github.com/dgraph-io/dgraph / processCustomFields

Method processCustomFields

query/outputnode_graphql.go:609–677  ·  view source on GitHub ↗
(field gqlSchema.Field, n fastJsonNode)

Source from the content-addressed store, hash-verified

607}
608
609func (genc *graphQLEncoder) processCustomFields(field gqlSchema.Field, n fastJsonNode) {
610 if field.HasCustomHTTPChild() {
611 // initially, create attr ids for all the descendents of this field,
612 // so that they don't result in race-conditions later
613 genc.initChildAttrId(field)
614 // TODO(abhimanyu):
615 // * benchmark the approach of using channels vs mutex to update the fastJson tree.
616 // * benchmark and find how much load should be put on HttpClient concurrently.
617 // * benchmark and find a default buffer capacity for these channels
618 genc.errCh = make(chan x.GqlErrorList, 3)
619 genc.customFieldResultCh = make(chan customFieldResult, 3)
620 // initialize WaitGroup for the error and result channel goroutines
621 wg := &sync.WaitGroup{}
622 wg.Add(2)
623 // keep collecting errors arising from custom field resolution until channel is closed
624 go func() {
625 for errs := range genc.errCh {
626 genc.errs = append(genc.errs, errs...)
627 }
628 wg.Done()
629 }()
630 // keep updating the fastJson tree as long as we get updates from the channel.
631 // This is the step-7 of *genc.resolveCustomField()
632 go func() {
633 // this would add the custom fastJson nodes in an arbitrary order. So, they may not
634 // be linked in the order the custom fields are present in selection set.
635 // i.e., while encoding the GraphQL response, we will have to do one of these:
636 // * a linear search to find the correct fastJson node for a custom field, or
637 // * first fix the order of custom fastJson nodes and then continue the encoding, or
638 // * create a map from custom fastJson node attr to the custom fastJson node,
639 // so that whenever a custom field is encountered in the selection set,
640 // just use the map to find out the fastJson node for that field.
641 // The last option seems better.
642
643 // the results slice keeps all the customFieldResults in memory as is, until all the
644 // custom fields aren't resolved. Once the channel is closed, it would update the
645 // fastJson tree serially, so that there are no race conditions.
646 results := make([]customFieldResult, 0)
647 for res := range genc.customFieldResultCh {
648 results = append(results, res)
649 }
650 for _, res := range results {
651 childAttr := genc.idForAttr(res.childField.DgraphAlias())
652 for _, parent := range res.parents {
653 childNode, err := genc.makeCustomNode(childAttr, res.childVal)
654 if err != nil {
655 genc.errCh <- x.GqlErrorList{res.childField.GqlErrorf(nil, "%s", err.Error())}
656 continue
657 }
658 childNode.next = parent.child
659 parent.child = childNode
660 }
661 }
662 wg.Done()
663 }()
664 // extract the representations for Apollo _entities query and store them in GraphQL encoder
665 if q, ok := field.(gqlSchema.Query); ok && q.QueryType() == gqlSchema.EntitiesQuery {
666 // ignore the error here, as that should have been taken care of during query rewriting

Callers 1

toGraphqlJSONMethod · 0.80

Calls 15

initChildAttrIdMethod · 0.95
resolveCustomFieldsMethod · 0.95
idForAttrMethod · 0.80
makeCustomNodeMethod · 0.80
childrenMethod · 0.80
WaitMethod · 0.80
HasCustomHTTPChildMethod · 0.65
DgraphAliasMethod · 0.65
GqlErrorfMethod · 0.65
QueryTypeMethod · 0.65
RepresentationsArgMethod · 0.65
SelectionSetMethod · 0.65

Tested by

no test coverage detected