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 ¶
- func Acquire(ctx context.Context, limiter *semaphore.Weighted) error
- func ForEach[T any](ctx context.Context, limiter *semaphore.Weighted, items []T, ...) error
- func ForEachBounded[T any](ctx context.Context, maxConcurrency int, items []T, ...) error
- func NewErrgroup(ctx context.Context, maxConcurrency int) (*errgroup.Group, context.Context)
- func NewLimiter(maxConcurrency int) *semaphore.Weighted
- func PanicSafeRelease(limiter *semaphore.Weighted)
- func Release(limiter *semaphore.Weighted)
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
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 ¶
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 ¶
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 ¶
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).
Types ¶
This section is empty.