Skip to content

Make worker_limit configurable at runtime (startup and per-request) - #4270

Open
grzn wants to merge 1 commit into
99designs:masterfrom
grzn:runtime-configurable-worker-limit
Open

Make worker_limit configurable at runtime (startup and per-request)#4270
grzn wants to merge 1 commit into
99designs:masterfrom
grzn:runtime-configurable-worker-limit

Conversation

@grzn

@grzn grzn commented Jul 15, 2026

Copy link
Copy Markdown

Closes #4269

Problem

exec.worker_limit is only configurable at codegen time. gqlgen bakes it into every generated graphql.MarshalSliceConcurrently(...) call as a compile-time literal, so the slice-marshalling concurrency limit is frozen at generation time — changing it means editing gqlgen.yml and regenerating.

graphql.MarshalSliceConcurrently already takes workerLimit int64 at runtime (0 = unlimited), so only the hard-coded literal prevented runtime configuration.

Change

Make the worker limit resolvable at runtime, with precedence:

per-request override > server-wide default > codegen worker_limit (fallback).

  • graphql.OperationContext gains a WorkerLimit *int64 field plus EffectiveWorkerLimit(codegenDefault int64) int64 and SetWorkerLimit(limit int64) helpers. *int64 keeps "unset" distinct from an explicit 0 (= unlimited).
  • executor.Executor and handler.Server gain SetWorkerLimit(int64) for a server-wide default, copied into each OperationContext in CreateOperationContext.
  • Per-request overrides can be set from an extension/middleware via graphql.GetOperationContext(ctx).SetWorkerLimit(n).
  • codegen (codegen/type.gotpl) now emits ec.EffectiveWorkerLimit({{ .Config.Exec.WorkerLimit }}) instead of the raw literal, keeping the YAML value as the default. ec is in scope in both execution-context syntax modes (receiver and function-syntax), so no extra plumbing is needed.

Generated files were regenerated with go generate ./....

Backward compatibility

Fully backward compatible. With nothing set at runtime, EffectiveWorkerLimit returns the codegen default, so behaviour is identical to before. MarshalSliceConcurrently's signature is unchanged, so example/testdata code that still passes the literal (nested modules not covered by go generate ./...) keeps compiling.

Usage

// server-wide at startup
srv.SetWorkerLimit(1000)

// per request, e.g. based on headers / complexity
srv.AroundOperations(func(ctx context.Context, next graphql.OperationHandler) graphql.ResponseHandler {
    graphql.GetOperationContext(ctx).SetWorkerLimit(4)
    return next(ctx)
})

I have:

  • Added tests covering the feature (graphql.TestEffectiveWorkerLimit)
  • Updated relevant documentation (docs/content/config.md)

@grzn
grzn requested a review from StevenACoffman as a code owner July 15, 2026 10:26
@grzn
grzn force-pushed the runtime-configurable-worker-limit branch from 31e3876 to 0fc79c2 Compare July 15, 2026 10:30
…est)

exec.worker_limit was baked into generated code as a compile-time literal,
so the slice-marshalling concurrency limit could only be changed by editing
gqlgen.yml and regenerating. This adds runtime configuration.

Precedence: per-request override > server-wide default > codegen worker_limit.

- graphql.OperationContext gains a WorkerLimit *int64 field plus
  EffectiveWorkerLimit(codegenDefault) and SetWorkerLimit(limit) helpers.
- Executor/Server gain SetWorkerLimit(int64) for a server-wide default,
  copied into each OperationContext in CreateOperationContext.
- Per-request overrides can be set from an extension/middleware via
  graphql.GetOperationContext(ctx).SetWorkerLimit(n).
- codegen emits ec.EffectiveWorkerLimit(<worker_limit>) instead of the raw
  literal, keeping the YAML value as the fallback default.

Fully backward compatible: with nothing set EffectiveWorkerLimit returns the
codegen default, so behaviour is unchanged. MarshalSliceConcurrently's
signature is untouched.
@grzn
grzn force-pushed the runtime-configurable-worker-limit branch from 0fc79c2 to 31e0145 Compare July 15, 2026 12:06
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Allow configuring worker_limit at runtime (server startup and per-request)

1 participant