Advanced Concurrency Patterns
Building on the concurrency fundamentals, this chapter explores production-grade patterns used in real-world Go applications.Worker Pool Pattern
A worker pool limits the number of concurrent goroutines to prevent resource exhaustion.Generic Worker Pool
Pipeline Pattern
Pipelines are a series of stages connected by channels, where each stage is a group of goroutines running the same function.Pipeline with Context (Cancellation)
Fan-Out / Fan-In Pattern
Fan-out: Multiple goroutines read from the same channel until it’s closed. Fan-in: A function reads from multiple inputs and multiplexes onto a single channel.Semaphore Pattern
Limit concurrent access to a resource using a buffered channel as a semaphore.Using golang.org/x/sync/semaphore
Rate Limiter Pattern
Control the rate of operations using a ticker.Using golang.org/x/time/rate
Circuit Breaker Pattern
Prevent cascading failures by temporarily blocking requests to a failing service.Error Group Pattern
errgroup manages a group of goroutines and returns the first error encountered.
Error Group with Limit
Publish-Subscribe Pattern
Graceful Shutdown Pattern
Sync Primitives Deep Dive
sync.Once
Execute initialization code exactly once, safely across goroutines.sync.Pool
Reuse objects to reduce allocations.sync.Map
Concurrent map optimized for specific use cases.sync.Cond
Wait for and signal conditions.Interview Questions
What's the difference between buffered and unbuffered channels?
What's the difference between buffered and unbuffered channels?
- Unbuffered: Synchronous. Sender blocks until receiver is ready.
- Buffered: Asynchronous up to capacity. Sender only blocks when buffer is full.
How would you implement a timeout for a goroutine?
How would you implement a timeout for a goroutine?
Use
context.WithTimeout or time.After with select:What causes a goroutine leak and how do you prevent it?
What causes a goroutine leak and how do you prevent it?
Goroutine leaks occur when goroutines are blocked forever (waiting on channels that never receive/send). Prevent by:
- Always closing channels when done
- Using
contextfor cancellation - Using
selectwith done channels - Avoiding sending to nil channels
When should you use sync.Map vs a regular map with mutex?
When should you use sync.Map vs a regular map with mutex?
Use
sync.Map when:- Keys are only ever written once but read many times
- Goroutines operate on disjoint sets of keys
sync.RWMutex for general-purpose concurrent access.Summary
| Pattern | Use Case |
|---|---|
| Worker Pool | Limit concurrent goroutines, process jobs |
| Pipeline | Chain processing stages |
| Fan-Out/Fan-In | Distribute work, collect results |
| Semaphore | Limit access to resources |
| Rate Limiter | Control operation frequency |
| Circuit Breaker | Prevent cascading failures |
| Error Group | Manage goroutine errors |
| Pub/Sub | Event-driven communication |