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.

Reply via email to