How do goroutines get cleaned up? For example, in many of these examples they create a goroutine that is supposed to send a message over a blocking channel eventually. What if I use their "select + time.After()" pattern and the timeout hits and I return. Does the goroutine hang forever? Does it constitute a memory leak? We both hold the channel, so it can't get garbage collected, is Go smart enough to know there aren't any more readers and the goroutine + channel can get cleaned up?
Maybe to solve this I use a "quit" channel as they do. Do I need to worry about what happens if a quit message is never sent, or if two routines send one, or if the receiver is multiplexed and only one of many readers gets the message and cleans up correctly. It sounds like the whole malloc() and free() dance all over again, except this time I don't have any nice invariants to reason about such as "Everything that gets malloc()ed needs to be free()d, exactly once". Instead I need to worry that everyone is playing nice and will terminate when asked, and I need to remember to ask exactly once.
Maybe to solve this I use a "quit" channel as they do. Do I need to worry about what happens if a quit message is never sent, or if two routines send one, or if the receiver is multiplexed and only one of many readers gets the message and cleans up correctly. It sounds like the whole malloc() and free() dance all over again, except this time I don't have any nice invariants to reason about such as "Everything that gets malloc()ed needs to be free()d, exactly once". Instead I need to worry that everyone is playing nice and will terminate when asked, and I need to remember to ask exactly once.