github.com/mstephano/gqlgen-schemagen@v0.0.0-20230113041936-dd2cd4ea46aa/graphql/fieldset.go (about) 1 package graphql 2 3 import ( 4 "io" 5 "sync" 6 ) 7 8 type FieldSet struct { 9 fields []CollectedField 10 Values []Marshaler 11 delayed []delayedResult 12 } 13 14 type delayedResult struct { 15 i int 16 f func() Marshaler 17 } 18 19 func NewFieldSet(fields []CollectedField) *FieldSet { 20 return &FieldSet{ 21 fields: fields, 22 Values: make([]Marshaler, len(fields)), 23 } 24 } 25 26 func (m *FieldSet) Concurrently(i int, f func() Marshaler) { 27 m.delayed = append(m.delayed, delayedResult{i: i, f: f}) 28 } 29 30 func (m *FieldSet) Dispatch() { 31 if len(m.delayed) == 1 { 32 // only one concurrent task, no need to spawn a goroutine or deal create waitgroups 33 d := m.delayed[0] 34 m.Values[d.i] = d.f() 35 } else if len(m.delayed) > 1 { 36 // more than one concurrent task, use the main goroutine to do one, only spawn goroutines for the others 37 38 var wg sync.WaitGroup 39 for _, d := range m.delayed[1:] { 40 wg.Add(1) 41 go func(d delayedResult) { 42 m.Values[d.i] = d.f() 43 wg.Done() 44 }(d) 45 } 46 47 m.Values[m.delayed[0].i] = m.delayed[0].f() 48 wg.Wait() 49 } 50 } 51 52 func (m *FieldSet) MarshalGQL(writer io.Writer) { 53 writer.Write(openBrace) 54 for i, field := range m.fields { 55 if i != 0 { 56 writer.Write(comma) 57 } 58 writeQuotedString(writer, field.Alias) 59 writer.Write(colon) 60 m.Values[i].MarshalGQL(writer) 61 } 62 writer.Write(closeBrace) 63 }