diff --git a/codegen/config/exec.go b/codegen/config/exec.go index cc19bcc671..c9a5b6bc29 100644 --- a/codegen/config/exec.go +++ b/codegen/config/exec.go @@ -21,7 +21,7 @@ type ExecConfig struct { FilenameTemplate string `yaml:"filename_template,omitempty"` // String template with {name} as placeholder for base name. DirName string `yaml:"dir"` - WorkerLimit uint `yaml: "worker_limit"` + WorkerLimit uint `yaml:"worker_limit"` } type ExecLayout string diff --git a/codegen/generated!.gotpl b/codegen/generated!.gotpl index 7f526a2174..8638b1cf9a 100644 --- a/codegen/generated!.gotpl +++ b/codegen/generated!.gotpl @@ -10,6 +10,7 @@ {{ reserveImport "bytes" }} {{ reserveImport "embed" }} +{{ reserveImport "golang.org/x/sync/semaphore"}} {{ reserveImport "github.com/vektah/gqlparser/v2" "gqlparser" }} {{ reserveImport "github.com/vektah/gqlparser/v2/ast" }} {{ reserveImport "github.com/99designs/gqlgen/graphql" }} diff --git a/codegen/type.gotpl b/codegen/type.gotpl index 1898d44460..aa143b1f22 100644 --- a/codegen/type.gotpl +++ b/codegen/type.gotpl @@ -101,6 +101,9 @@ ret := make(graphql.Array, len(v)) {{- if not $type.IsScalar }} var wg sync.WaitGroup + {{- if gt $.Config.Exec.WorkerLimit 0 }} + sm := semaphore.NewWeighted({{ $.Config.Exec.WorkerLimit }}) + {{- end }} isLen1 := len(v) == 1 if !isLen1 { wg.Add(len(v)) @@ -124,14 +127,29 @@ }() {{- end }} if !isLen1 { - defer wg.Done() + {{- if gt $.Config.Exec.WorkerLimit 0 }} + defer func(){ + sm.Release(1) + wg.Done() + }() + {{- else }} + defer wg.Done() + {{- end }} } ret[i] = ec.{{ $type.Elem.MarshalFunc }}(ctx, sel, v[i]) } if isLen1 { f(i) } else { - go f(i) + {{- if gt $.Config.Exec.WorkerLimit 0 }} + if err := sm.Acquire(ctx, 1); err != nil { + ec.Error(ctx, ctx.Err()) + } else { + go f(i) + } + {{- else }} + go f(i) + {{- end }} } {{ else }} ret[i] = ec.{{ $type.Elem.MarshalFunc }}(ctx, sel, v[i])