On Tuesday, July 9, 2019 at 12:27:32 PM UTC-4, Dan Eloff wrote: > > I couldn't use <-channel.Close since in my case the goroutine isn't > guaranteed to have something sent, so that would leak goroutines. I added a > cleanup goroutine to scan timed-out channels and close them, which solves > this problem. But now I can use that close as a signal to the receiver than > the a timeout happened, and eliminate the select and the race entirely. The > close can in rare cases race with the sender, but that's easily enough > fixed: > > // TrySend tries to send on a possibly closed channel and handles the > panic if necessary. > // Returns true if conn was successfully sent over the channel. > func (waiter *Waiter) TrySend(conn Connection) (sent bool) { > defer func() { > r := recover() > sent = r != nil > }() > waiter.channel <- conn > return > } > > So I guess the best thing to do in these cases is don't combine select with > sending unmanaged resources over a channel. It's probably worth warning > about this problem in the docs for select? It's not an obvious gotcha. >
The best thing to do is to not use unmanaged resources. This is obviously not always possible, but when you *have* to use unmanaged resources, and you care about cleaning them up, you must use a lot of care. This is not a problem specific to select. It is possible to correctly use select with unmanaged resources. It just takes more thought, and a really solid understanding of the language and the principals of concurrency and ownership to get it right. -- You received this message because you are subscribed to the Google Groups "golang-nuts" group. To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts+unsubscr...@googlegroups.com. To view this discussion on the web visit https://groups.google.com/d/msgid/golang-nuts/683f05e8-00d3-4480-90f9-e8c114cb5ca1%40googlegroups.com. For more options, visit https://groups.google.com/d/optout.