Install
Terminal · npx$
npx skills add https://github.com/microsoft/github-copilot-for-azure --skill azure-messagingWorks with Paperclip
How Golang Concurrency fits into a Paperclip company.
Golang Concurrency drops into any Paperclip agent that handles this kind of work. Assign it to a specialist inside a pre-configured PaperclipOrg company and the skill becomes available on every heartbeat — no prompt engineering, no tool wiring.
S
SaaS FactoryPaired
Pre-configured AI company — 18 agents, 18 skills, one-time purchase.
$27$59
Explore packSource file
SKILL.md133 linesExpandCollapse
---name: golang-concurrencydescription: "Golang concurrency patterns. Use when writing or reviewing concurrent Go code involving goroutines, channels, select, locks, sync primitives, errgroup, singleflight, worker pools, or fan-out/fan-in pipelines. Also triggers when you detect goroutine leaks, race conditions, channel ownership issues, or need to choose between channels and mutexes."user-invocable: truelicense: MITcompatibility: Designed for Claude Code or similar AI coding agents, and for projects using Golang.metadata: author: samber version: "1.1.2" openclaw: emoji: "⚡" homepage: https://github.com/samber/cc-skills-golang requires: bins: - go install: []allowed-tools: Read Edit Write Glob Grep Bash(go:*) Bash(golangci-lint:*) Bash(git:*) Agent AskUserQuestion--- **Persona:** You are a Go concurrency engineer. You assume every goroutine is a liability until proven necessary — correctness and leak-freedom come before performance. **Modes:** - **Write mode** — implement concurrent code (goroutines, channels, sync primitives, worker pools, pipelines). Follow the sequential instructions below.- **Review mode** — reviewing a PR's concurrent code changes. Focus on the diff: check for goroutine leaks, missing context propagation, ownership violations, and unprotected shared state. Sequential.- **Audit mode** — auditing existing concurrent code across a codebase. Use up to 5 parallel sub-agents as described in the "Parallelizing Concurrency Audits" section. > **Community default.** A company skill that explicitly supersedes `samber/cc-skills-golang@golang-concurrency` skill takes precedence. # Go Concurrency Best Practices Go's concurrency model is built on goroutines and channels. Goroutines are cheap but not free — every goroutine you spawn is a resource you must manage. The goal is structured concurrency: every goroutine has a clear owner, a predictable exit, and proper error propagation. ## Core Principles 1. **Every goroutine must have a clear exit** — without a shutdown mechanism (context, done channel, WaitGroup), they leak and accumulate until the process crashes2. **Share memory by communicating** — channels transfer ownership explicitly; mutexes protect shared state but make ownership implicit3. **Send copies, not pointers** on channels — sending pointers creates invisible shared memory, defeating the purpose of channels4. **Only the sender closes a channel** — closing from the receiver side panics if the sender writes after close5. **Specify channel direction** (`chan<-`, `<-chan`) — the compiler prevents misuse at build time6. **Default to unbuffered channels** — larger buffers mask backpressure; use them only with measured justification7. **Always include `ctx.Done()` in select** — without it, goroutines leak after caller cancellation8. **Never use `time.After` in loops** — each call creates a timer that lives until it fires, accumulating memory. Use `time.NewTimer` + `Reset`9. **Track goroutine leaks in tests** with `go.uber.org/goleak` For detailed channel/select code examples, see [Channels and Select Patterns](references/channels-and-select.md). ## Channel vs Mutex vs Atomic | Scenario | Use | Why || --- | --- | --- || Passing data between goroutines | Channel | Communicates ownership transfer || Coordinating goroutine lifecycle | Channel + context | Clean shutdown with select || Protecting shared struct fields | `sync.Mutex` / `sync.RWMutex` | Simple critical sections || Simple counters, flags | `sync/atomic` | Lock-free, lower overhead || Many readers, few writers on a map | `sync.Map` | Optimized for read-heavy workloads. **Concurrent map read/write causes a hard crash** || Caching expensive computations | `sync.Once` / `singleflight` | Execute once or deduplicate | ## WaitGroup vs errgroup | Need | Use | Why || --- | --- | --- || Wait for goroutines, errors not needed | `sync.WaitGroup` | Fire-and-forget || Wait + collect first error | `errgroup.Group` | Error propagation || Wait + cancel siblings on first error | `errgroup.WithContext` | Context cancellation on error || Wait + limit concurrency | `errgroup.SetLimit(n)` | Built-in worker pool | ## Sync Primitives Quick Reference | Primitive | Use case | Key notes || --- | --- | --- || `sync.Mutex` | Protect shared state | Keep critical sections short; never hold across I/O || `sync.RWMutex` | Many readers, few writers | Never upgrade RLock to Lock (deadlock) || `sync/atomic` | Simple counters, flags | Prefer typed atomics (Go 1.19+): `atomic.Int64`, `atomic.Bool` || `sync.Map` | Concurrent map, read-heavy | No explicit locking; use `RWMutex`+map when writes dominate || `sync.Pool` | Reuse temporary objects | Always `Reset()` before `Put()`; reduces GC pressure || `sync.Once` | One-time initialization | Go 1.21+: `OnceFunc`, `OnceValue`, `OnceValues` || `sync.WaitGroup` | Wait for goroutine completion | `Add` before `go`; Go 1.24+: `wg.Go()` simplifies usage || `x/sync/singleflight` | Deduplicate concurrent calls | Cache stampede prevention || `x/sync/errgroup` | Goroutine group + errors | `SetLimit(n)` replaces hand-rolled worker pools | For detailed examples and anti-patterns, see [Sync Primitives Deep Dive](references/sync-primitives.md). ## Concurrency Checklist Before spawning a goroutine, answer: - [ ] **How will it exit?** — context cancellation, channel close, or explicit signal- [ ] **Can I signal it to stop?** — pass `context.Context` or done channel- [ ] **Can I wait for it?** — `sync.WaitGroup` or `errgroup`- [ ] **Who owns the channels?** — creator/sender owns and closes- [ ] **Should this be synchronous instead?** — don't add concurrency without measured need ## Pipelines and Worker Pools For pipeline patterns (fan-out/fan-in, bounded workers, generator chains, Go 1.23+ iterators, `samber/ro`), see [Pipelines and Worker Pools](references/pipelines.md). ## Parallelizing Concurrency Audits When auditing concurrency across a large codebase, use up to 5 parallel sub-agents (Agent tool): 1. Find all goroutine spawns (`go func`, `go method`) and verify shutdown mechanisms2. Search for mutable globals and shared state without synchronization3. Audit channel usage — ownership, direction, closure, buffer sizes4. Find `time.After` in loops, missing `ctx.Done()` in select, unbounded spawning5. Check mutex usage, `sync.Map`, atomics, and thread-safety documentation ## Common Mistakes | Mistake | Fix || --- | --- || Fire-and-forget goroutine | Provide stop mechanism (context, done channel) || Closing channel from receiver | Only the sender closes || `time.After` in hot loop | Reuse `time.NewTimer` + `Reset` || Missing `ctx.Done()` in select | Always select on context to allow cancellation || Unbounded goroutine spawning | Use `errgroup.SetLimit(n)` or semaphore || Sharing pointer via channel | Send copies or immutable values || `wg.Add` inside goroutine | Call `Add` before `go` — `Wait` may return early otherwise || Forgetting `-race` in CI | Always run `go test -race ./...` || Mutex held across I/O | Keep critical sections short | ## Cross-References - -> See `samber/cc-skills-golang@golang-performance` skill for false sharing, cache-line padding, `sync.Pool` hot-path patterns- -> See `samber/cc-skills-golang@golang-context` skill for cancellation propagation and timeout patterns- -> See `samber/cc-skills-golang@golang-safety` skill for concurrent map access and race condition prevention- -> See `samber/cc-skills-golang@golang-troubleshooting` skill for debugging goroutine leaks and deadlocks- -> See `samber/cc-skills-golang@golang-design-patterns` skill for graceful shutdown patterns ## References - [Go Concurrency Patterns: Pipelines](https://go.dev/blog/pipelines)- [Effective Go: Concurrency](https://go.dev/doc/effective_go#concurrency)