Help us shape the future of Go! Take the 2026 Go Developer Survey

concurrency

package
v5.7.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Nov 2, 2026 License: Apache-2.0 Imports: 3 Imported by: 0

Documentation

Overview

Package concurrency holds the helpers Compose uses to bound how many operations run at once, driven by the --parallel setting.

Across Compose, a bound of zero or less means "unlimited" (the Go zero value of a configured maximum must never stall a command). This is not what the underlying primitives do: errgroup.SetLimit(0) allows zero goroutines, so a plain SetLimit call with an unset maximum hangs forever. Every helper here applies the "<= 0 means unlimited" rule in one place.

The package is a leaf: it depends on no other Compose package.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func Acquire

func Acquire(ctx context.Context, limiter *semaphore.Weighted) error

Acquire takes a slot from limiter, or is a no-op when limiter is nil.

func ForEach

func ForEach[T any](ctx context.Context, limiter *semaphore.Weighted, items []T, fn func(context.Context, T) error) error

ForEach runs fn concurrently for each item, bounded by limiter, and returns the first error, cancelling the context passed to the other calls. Unlike NewErrgroup, limiter is built by the caller and can be shared across several concurrently-dispatched calls, so the combined concurrency of all of them never exceeds the configured budget. A nil limiter means unbounded.

func ForEachBounded

func ForEachBounded[T any](ctx context.Context, maxConcurrency int, items []T, fn func(context.Context, T) error) error

ForEachBounded runs fn concurrently for each item, at most maxConcurrency at a time (0 meaning no bound), and returns the first error, cancelling the context passed to the other calls. Use ForEach instead when the concurrency budget must be shared across several concurrently-dispatched calls, e.g. one per service visited by InDependencyOrder.

func NewErrgroup

func NewErrgroup(ctx context.Context, maxConcurrency int) (*errgroup.Group, context.Context)

NewErrgroup returns an errgroup.Group, with the context it derives, running at most maxConcurrency goroutines at once. maxConcurrency <= 0 leaves it unlimited, since errgroup.SetLimit(0) means "allow zero goroutines", not "unlimited".

func NewLimiter

func NewLimiter(maxConcurrency int) *semaphore.Weighted

NewLimiter returns a semaphore bounding concurrency to maxConcurrency, or nil when maxConcurrency <= 0 (unlimited). Use it, with Acquire and Release, to gate only part of a goroutine's work (e.g. the opening call of an indefinite stream, not the stream itself), or to share one budget between several concurrent calls (see ForEach), where NewErrgroup's whole-goroutine bound does not apply.

func PanicSafeRelease

func PanicSafeRelease(limiter *semaphore.Weighted)

PanicSafeRelease is deferred by callers that release a slot earlier than function exit on the success path, to avoid leaking it if the guarded call panics before reaching that point. It is a no-op unless the deferring goroutine is unwinding from a panic, in which case it releases the slot and re-panics. It must be deferred directly (recover only works there).

func Release

func Release(limiter *semaphore.Weighted)

Release gives back a slot taken via Acquire, or is a no-op when limiter is nil.

Types

This section is empty.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL