external/cc-skills-golang/golang-concurrency/SKILL.md
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.
npx skillsauth add seikaikyo/dash-skills golang-concurrencyInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
Persona: You are a Go concurrency engineer. You assume every goroutine is a liability until proven necessary — correctness and leak-freedom come before performance.
Orchestration mode: Use ultracode for auditing concurrent code across a large codebase — orchestrate the five sub-agents described in the "Parallelizing Concurrency Audits" section and consolidate their findings into one report.
Modes:
Community default. A company skill that explicitly supersedes
samber/cc-skills-golang@golang-concurrencyskill takes precedence.
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.
chan<-, <-chan) — the compiler prevents misuse at build timectx.Done() in select — without it, goroutines leak after caller cancellationtime.After in hot loops — each call allocates a timer and creates unnecessary churn; use time.NewTimer + Reset for long-running loopsgo.uber.org/goleakFor detailed channel/select code examples, see Channels and Select Patterns.
| 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 |
| 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 |
| 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 | Waiting for simple goroutines | Go 1.25+: prefer wg.Go(func(){ ... }) for fire-and-wait tasks that do not panic and do not need error propagation. For Go <1.25 use Add/Done. For errors/cancellation/limits, use errgroup with context. |
| 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.
Before spawning a goroutine, answer:
context.Context or done channelsync.WaitGroup or errgroupFor pipeline patterns (fan-out/fan-in, bounded workers, generator chains, Go 1.23+ iterators, samber/ro), see Pipelines and Worker Pools.
When auditing concurrency across a large codebase, use up to 5 parallel sub-agents (Agent tool):
go func, go method) and verify shutdown mechanismstime.After in loops, missing ctx.Done() in select, unbounded spawningsync.Map, atomics, and thread-safety documentation| 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 |
samber/cc-skills-golang@golang-performance skill for false sharing, cache-line padding, sync.Pool hot-path patternssamber/cc-skills-golang@golang-context skill for cancellation propagation and timeout patternssamber/cc-skills-golang@golang-safety skill for concurrent map access and race condition preventionsamber/cc-skills-golang@golang-troubleshooting skill for debugging goroutine leaks and deadlockssamber/cc-skills-golang@golang-design-patterns skill for graceful shutdown patternssamber/cc-skills-golang@golang-continuous-integration skill for automated AI-driven code review in CI using these guidelinesFor Go 1.26 diagnostics, there is an experimental goroutine leak profile. It is useful for production-oriented leak investigation, but is gated by GOEXPERIMENT=goroutineleakprofile; do not rely on it as default stable behavior.
Typical usage when the experiment is enabled:
curl http://localhost:6060/debug/pprof/goroutineleak?debug=2
go tool pprof http://localhost:6060/debug/pprof/goroutineleak
Keep existing tools:
go.uber.org/goleakruntime.NumGoroutine()/debug/pprof/goroutine?debug=2go test -race ./...development
拋棄式 HTML mockup 比稿:產出 2 到 3 個設計立場不同的變體(密度 / 版式 / 強調軸,不是換色),各附取捨說明,最後給有立場的對比結論。適用:「畫個草圖」「比較 A 版 B 版」「先看方向再做」「給我看幾種做法」。要 production 元件或設計已定案時不適用。
tools
需求不明時的意圖萃取訪談:一次一題、每題附上自己的猜測、聽出「真正想要 vs 覺得應該要」,直到能預測使用者反應(約 95% 信心)才動工。適用:需求缺少對象 / 動機 / 成功標準 / 約束,或使用者點名「訪談我」「先確認一下」「我們確定嗎」。明確自足的指示、純資訊查詢、機械性操作不適用。
development
對非平凡決策啟動新鮮 context 對抗審查(找碴不背書),在修正還便宜的時候抓出錯誤方向。適用:高風險改動(production、資安敏感邏輯、不可逆操作)、不熟的程式碼、要宣稱「這樣是安全的 / 可行的」之前。機械性操作與一行修改不適用。
testing
Reference for writing and editing agent skills well — the vocabulary and principles that make a skill predictable. Consult when authoring, reviewing, or pruning a SKILL.md.