Module 3 · Exercise 2 · ~40 min · Real Go code
Build a bounded-concurrency worker pool with proper context handling and first-error-wins propagation. The same shape as errgroup.Group in the wild — and the shape you'll use for parallel command submission, parallel queries, parallel anything.
cd module-03-concurrency/exercises/exercise-02-worker-pool
go test -v -race ./...
err := workerpool.Run(ctx, workers, tasks)
That's the whole API. Underneath, the pool must:
workers tasks concurrently.ctx is canceled externally, propagate that cancellation to running tasks (via their ctx argument) and stop dispatching new ones.ctx with context.WithCancel. Pass it to tasks and cancel it on first error.select { case errCh <- err: default: } captures the first and drops the rest non-blockingly.sync.WaitGroup to know when workers finish.for-range it" pattern from Module 3 Lesson 1 is exactly the shape here.Real Canton-adjacent code does this everywhere — submitting a batch of commands in parallel, fetching state for many parties concurrently, processing a transaction-stream window. Once you've written this once, the production version (with metrics, with retries) is a small extension of the same shape.
The standard library's golang.org/x/sync/errgroup is essentially this — go read its source after passing tests.