Go concurrency primitives in addition to the ones provided by the language and sync/sync/atomic packages
npx @tessl/cli install tessl/golang-golang-org-x--sync@0.18.0The golang.org/x/sync package provides essential Go concurrency primitives that extend beyond the standard library's sync and sync/atomic packages. It offers higher-level abstractions for common concurrent programming patterns including goroutine group management, resource limiting, call deduplication, and concurrent maps.
go get golang.org/x/sync@v0.18.0Import sub-packages individually as needed:
import (
"golang.org/x/sync/errgroup"
"golang.org/x/sync/semaphore"
"golang.org/x/sync/singleflight"
"golang.org/x/sync/syncmap"
)Quick example using errgroup to manage concurrent tasks with error handling:
package main
import (
"context"
"fmt"
"golang.org/x/sync/errgroup"
)
func main() {
g, ctx := errgroup.WithContext(context.Background())
// Launch multiple concurrent tasks
g.Go(func() error {
// Task 1
return nil
})
g.Go(func() error {
// Task 2
return nil
})
// Wait for all tasks to complete
if err := g.Wait(); err != nil {
fmt.Printf("Error: %v\n", err)
}
}This package is organized into four independent sub-packages, each solving a specific concurrency problem:
Each sub-package can be used independently and follows Go's philosophy of simple, composable concurrency primitives.
The errgroup package provides coordination for groups of goroutines working on subtasks, with built-in error propagation and context cancellation. It's similar to sync.WaitGroup but adds error handling and goroutine limiting capabilities.
// Create a new group with context
func WithContext(ctx context.Context) (*Group, context.Context)
// Core errgroup.Group type
type Group struct {
// unexported fields
}
// Launch goroutines
func (g *Group) Go(f func() error)
func (g *Group) TryGo(f func() error) bool
// Wait for completion
func (g *Group) Wait() error
// Configure concurrency limits
func (g *Group) SetLimit(n int)The semaphore package implements weighted semaphores for controlling concurrent access to resources. Each acquire operation can request a custom weight, enabling flexible resource management scenarios like connection pooling or rate limiting.
// Create a weighted semaphore
func NewWeighted(n int64) *Weighted
// Core semaphore.Weighted type
type Weighted struct {
// unexported fields
}
// Acquire resources
func (s *Weighted) Acquire(ctx context.Context, n int64) error
func (s *Weighted) TryAcquire(n int64) bool
// Release resources
func (s *Weighted) Release(n int64)The singleflight package provides a mechanism to suppress duplicate function calls when multiple goroutines request the same resource simultaneously. This is especially useful for caching scenarios where you want only one goroutine to fetch data while others wait for the result.
// Core singleflight.Group type
type Group struct {
// unexported fields
}
// Execute with deduplication
func (g *Group) Do(key string, fn func() (interface{}, error)) (v interface{}, err error, shared bool)
func (g *Group) DoChan(key string, fn func() (interface{}, error)) <-chan Result
// Forget a key
func (g *Group) Forget(key string)
// Result type for channel-based operations
type Result struct {
Val interface{}
Err error
Shared bool
}The syncmap package provides a concurrent map implementation. It's a type alias to sync.Map from the standard library, which was originally prototyped in this package.
// Type alias to sync.Map
type Map = sync.MapMost packages in golang.org/x/sync integrate with Go's context package for cancellation:
errgroup.WithContext creates a group with automatic cancellation on first errorsemaphore.Acquire accepts a context to support cancellation while waitingAll types are designed with useful zero values:
errgroup.Group is valid (no goroutine limit, no automatic cancellation)singleflight.Group is valid (lazily initializes internal map)syncmap.Map is valid and emptySeveral packages provide "Try" variants for non-blocking operations:
errgroup.Group.TryGo attempts to start a goroutine without blockingsemaphore.Weighted.TryAcquire attempts to acquire without blockingThese enable optimistic concurrency patterns and prevent deadlocks in resource-constrained scenarios.