proxy: Fix Goroutine leak in `forwardClientToServers()`
The forwardClientToServers()
function forwards frames received from
the client to all servers. This forwarding happens async, where any
errors are reported back via an error channel.
This channel has a buffer of 1, and the single consumer of this buffer will only ever consume a single error from that channel. It follows that we mustn't ever try to send multiple errors via the same channel, or otherwise the Goroutine would deadlock trying to send if there's no consumer.
But we do try to send multiple errors in the case where we fail to properly receive a message from the client: we try to send both this error and the error of the errgroup through the channel. This has caused multiple incidents already where so many Goroutines were deadlocked that we accumulated multiple gigabytes of memory and eventually ran out of memory.
Fix the leak by only sending a single error: if receiving the message failed, we'll return this error. Otherwise, we'll return the error of the errgroup. With the goleak detector, we can furthermore demonstrate that there are no more Goroutine leaks after this patch.
Closes #3541 (closed)