While I see fewer unsynchronized go func() these days, they still appear often enough in regard to fire-and-forget work.
Unmanaged go func() results in unbounded concurrency, memory leaks, and other surprising behavior in a system.
So I traced a few repos at work to see how many of them appear irl. Turns out quite a bit in our huge monorepo.
I explored a tiny task manager that collects tasks as func() closures in a buffered channel and runs them in a bounded pool. It clamps down on unbounded concurrency, is aware of the parent context, allows task-specific timeouts, etc. All that requires less than 25 loc.
Might be interesting to you.
Update: I am aware of errgroup. It is not the right abstraction here as it cancels all inflight tasks if any of them fails. Also, the internal semaphore of errgroup works in a similar way as shown here
