4 ms·
This share by communicating mantra needs to die. Channel based code in go has a tendency to require nontrivial cleanup. Each time you need to compose a channel
by silasdavis 7y ago
This share by communicating mantra needs to die. Channel based code in go has a tendency to require nontrivial cleanup. Each time you need to compose a channel you you end up introducing another goroutine (for example just to map a type or merge multiple channels). Now that goroutine needs to be closed, then you end up with an additional close channel, and sometimes you need to drain channels to prevent locks.
They are not universally a bad thing, but total avoidance of sync package primitives is a bad idea (and much slower in many circumstances)
This gives a good analysis:
https://www.jtolio.com/2016/03/go-channels-are-bad-and-you-should-feel-bad/ https://www.jtolio.com/2016/03/go-channels-are-bad-and-you-s...
- majewsky 7y agoMost of these points are fair, but: > Now that goroutine needs to be closed, then you end up with an additional close channel Goroutines that just map values or similar will usually share a context with some other goroutine and can therefore reuse that context's close channel.
- deleted 7y ago[deleted]
- jerf 7y agoYeah, but you often still have to write the code that reacts to the context. The way context gets talked about in the Go community, it gives many programmers the impression that a context closing will somehow forcibly shut down a goroutine or something. There's a lot of "when the context is cancelled, it will...", but it really ought to be phrased more like "when the context is cancelled, you can...", something to the effect of "have code that catches that close and handles it properly". So, having a context is still "end[ing] up with an additional close channel" as silasdavis said. Even if you pass it to something that will be cancelled like a network operation, you still must correctly notice and handle the resulting timeout error. The value for context is almost entirely that everybody in the community has come to agree on it rather than its functionality per se. Which is the same as io.Reader, in that the utility isn't its functionality, which any number of languages can replicate, but the way everybody agrees to implement and use it through the entire ecosystem, which is where other languages have a lot more trouble. Nothing technically stops that from happening, but you often end up with islands of agreement in different major frameworks or library ecosystems instead of ecosystem-wide agreement. Context is everywhere now; it's actually been a few months since I encountered a place I wish that took it that didn't.
- api 7y agoFor simple cases mutexes and such can be much faster and simpler. Channel based constructs are good when they model the problem well as streaming or queuing.