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  }