We break down why “just run N goroutines” is not enough, and how to combine several parallel subtasks into one managed operation: waiting via
sync.WaitGroup, cancellation via
context.WithCancel, returning the “first error” via a buffered
errCh and a non-blocking send, and also collecting all errors via
errors.Join. Separately, we discuss
cancel() discipline, respecting
ctx.Done(), and common concurrency pitfalls.