PluginBench
Skill
Pass
Audit score 90

go-concurrency-patterns

wshobson/agents

Master Go concurrency with goroutines, channels, sync primitives, and context management.

What is go-concurrency-patterns?

Production patterns for Go concurrency including goroutines, channels, synchronization primitives, and context management. Use when building concurrent Go applications, implementing worker pools, managing goroutine lifecycles, or debugging race conditions.

  • Implement goroutines for lightweight concurrent execution
  • Use channels for safe communication between goroutines
  • Manage synchronization with sync.Mutex, sync.WaitGroup, and errgroup
  • Apply context for cancellation, deadlines, and timeout handling
  • Multiplex channel operations with select statements
  • Debug and prevent race conditions in concurrent code

How to install go-concurrency-patterns

npx skills add https://github.com/wshobson/agents --skill go-concurrency-patterns
Claude Code
Cursor
Windsurf
Cline

How to use go-concurrency-patterns

  1. 1.Review the core concurrency primitives table to understand goroutines, channels, sync.Mutex, sync.WaitGroup, and context.Context
  2. 2.Study the quick start example showing context-based worker pattern with WaitGroup
  3. 3.Read references/details.md for detailed pattern documentation and worked examples
  4. 4.Apply best practices: use context for cancellation, close channels from sender only, prefer channels over mutexes, and always provide goroutine exit paths
  5. 5.Test your concurrent code with race detector: go run -race your_program.go

Use cases

Good for
  • Building worker pool patterns for parallel task processing
  • Implementing graceful shutdown with context cancellation
  • Creating pipelines that process data through multiple concurrent stages
  • Managing goroutine lifecycles in long-running services
  • Coordinating multiple concurrent operations with proper error handling
Who it's for
  • Go backend developers
  • Systems engineers building concurrent services
  • DevOps engineers implementing concurrent tooling
  • Anyone building production Go applications with concurrency requirements

go-concurrency-patterns FAQ

When should I use channels vs mutexes?

Prefer channels for communication between goroutines; use mutexes only when you need to protect shared memory access. The Go concurrency mantra is: don't communicate by sharing memory; share memory by communicating.

How do I prevent goroutine leaks?

Always provide an exit path for every goroutine. Use context.Done() to listen for cancellation signals and ensure goroutines terminate when their work is complete or context is cancelled.

What's the difference between buffered and unbuffered channels?

Unbuffered channels block until both sender and receiver are ready. Buffered channels allow sends to proceed until the buffer is full. Use buffered channels when you know the count of messages.

How do I handle errors in concurrent operations?

Use errgroup package for concurrent operations that may error. It provides a simple way to synchronize goroutines and collect errors from multiple concurrent tasks.

Why should I use context instead of time.Sleep for synchronization?

context provides proper cancellation semantics and deadline support. time.Sleep is unreliable for synchronization and doesn't respond to cancellation signals.

Full instructions (SKILL.md)

Source of truth, from wshobson/agents.


name: go-concurrency-patterns description: Master Go concurrency with goroutines, channels, sync primitives, and context. Use when building concurrent Go applications, implementing worker pools, or debugging race conditions.

Go Concurrency Patterns

Production patterns for Go concurrency including goroutines, channels, synchronization primitives, and context management.

When to Use This Skill

  • Building concurrent Go applications
  • Implementing worker pools and pipelines
  • Managing goroutine lifecycles
  • Using channels for communication
  • Debugging race conditions
  • Implementing graceful shutdown

Core Concepts

1. Go Concurrency Primitives

PrimitivePurpose
goroutineLightweight concurrent execution
channelCommunication between goroutines
selectMultiplex channel operations
sync.MutexMutual exclusion
sync.WaitGroupWait for goroutines to complete
context.ContextCancellation and deadlines

2. Go Concurrency Mantra

Don't communicate by sharing memory;
share memory by communicating.

Quick Start

package main

import (
    "context"
    "fmt"
    "sync"
    "time"
)

func main() {
    ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
    defer cancel()

    results := make(chan string, 10)
    var wg sync.WaitGroup

    // Spawn workers
    for i := 0; i < 3; i++ {
        wg.Add(1)
        go worker(ctx, i, results, &wg)
    }

    // Close results when done
    go func() {
        wg.Wait()
        close(results)
    }()

    // Collect results
    for result := range results {
        fmt.Println(result)
    }
}

func worker(ctx context.Context, id int, results chan<- string, wg *sync.WaitGroup) {
    defer wg.Done()

    select {
    case <-ctx.Done():
        return
    case results <- fmt.Sprintf("Worker %d done", id):
    }
}

Detailed patterns and worked examples

Detailed pattern documentation lives in references/details.md. Read that file when the navigation tier above is insufficient.

Best Practices

Do's

  • Use context - For cancellation and deadlines
  • Close channels - From sender side only
  • Use errgroup - For concurrent operations with errors
  • Buffer channels - When you know the count
  • Prefer channels - Over mutexes when possible

Don'ts

  • Don't leak goroutines - Always have exit path
  • Don't close from receiver - Causes panic
  • Don't use shared memory - Unless necessary
  • Don't ignore context cancellation - Check ctx.Done()
  • Don't use time.Sleep for sync - Use proper primitives