Skip to content

Commit ab3b083

Browse files
committed
Experimental implementation of concurrently resolving fields
1 parent 09574d6 commit ab3b083

File tree

1 file changed

+41
-5
lines changed

1 file changed

+41
-5
lines changed

executor.go

Lines changed: 41 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -274,15 +274,51 @@ func executeFields(p ExecuteFieldsParams) *Result {
274274
p.Fields = map[string][]*ast.Field{}
275275
}
276276

277-
finalResults := map[string]interface{}{}
277+
type resolvedChanResult struct {
278+
responseName string
279+
resolved interface{}
280+
state resolveFieldResultState
281+
panicErr error
282+
}
283+
284+
// concurrently resolve fields
285+
var wg sync.WaitGroup
286+
resolvedChan := make(chan resolvedChanResult, len(p.Fields))
278287
for responseName, fieldASTs := range p.Fields {
279-
resolved, state := resolveField(p.ExecutionContext, p.ParentType, p.Source, fieldASTs)
280-
if state.hasNoFieldDefs {
288+
wg.Add(1)
289+
go func(responseName string, fieldASTs []*ast.Field) (resolved interface{}, state resolveFieldResultState, panicErr error) {
290+
defer func() {
291+
if r := recover(); r != nil {
292+
if r, ok := r.(error); ok {
293+
// recover panic that was thrown by resolveFields(),
294+
// indicating that we should short-circuit traversal chain later
295+
panicErr = r
296+
}
297+
}
298+
resolvedChan <- resolvedChanResult{responseName, resolved, state, panicErr}
299+
wg.Done()
300+
}()
301+
resolved, state = resolveField(p.ExecutionContext, p.ParentType, p.Source, fieldASTs)
302+
return resolved, state, panicErr
303+
}(responseName, fieldASTs)
304+
}
305+
306+
// wait for all routines to complete and then perform clean up
307+
wg.Wait()
308+
close(resolvedChan)
309+
310+
// iterate through resolved results
311+
finalResults := map[string]interface{}{}
312+
for result := range resolvedChan {
313+
if result.panicErr != nil {
314+
// short-circuit field resolution traversal chain
315+
panic(result.panicErr)
316+
}
317+
if result.state.hasNoFieldDefs {
281318
continue
282319
}
283-
finalResults[responseName] = resolved
320+
finalResults[result.responseName] = result.resolved
284321
}
285-
286322
return &Result{
287323
Data: finalResults,
288324
Errors: p.ExecutionContext.Errors(),

0 commit comments

Comments
 (0)