Channels are very useful and necessary to really get your program using all the resources at your disposal. Doing that with locks or callbacks is error prone and makes solving some problems all but impossible. Let me give you an example of a pattern we used a few days ago:
We were processing message from a queue, writing some data to Cassandra, and then committing offsets when the work was completed. It was really important for the commits to come out in the same order they came in, so that we never commit an offset when we haven't actually written all the data. (on crash or restart its ok to process the same messages again because the writing is idempotent) Modeled as a pipeline we had a few stages: intake -> decode -> encode -> write to cassandra -> commit The naive approach would be to spin up a bunch of writer goroutines, but then the order of messages to commit would be unpredictable. Instead we created two slices of channels: ins := make([]chan intakeMessage, options.workers) outs := make([]chan commitMessage, options.workers) And spun up goroutines that read from one of the input channels and wrote to the corresponding out channel: for i := 0; i < options.workers; i++ { ins[i] = make(chan intakeMessage, 1) outs[i] := make(chan commitMessage, 1) go worker(ins[i], outs[i]) } We then use these slices as a circular buffer and keep track of two pointers, one for the next available in and another for the next remaining out. There are 3 cases: 1. The slice is empty, in which case we insert at 0 and increment the in counter 2. The slice is full (all workers are busy), in which case we wait until a result is pushed into the channel at the out counter 3. We're somewhere in between, in which case we use a select on either the next available in channel or the next remaining out counter So all the commits come out in the order they came in, we get nice parallelism and there's no blocking or polling. There is overhead to channels but if you send messages of adequate size you'll barely notice it in real programs. Batch and send slices. The thing I find remarkable about channels and goroutines is how often the solutions for improving the performance of a Go program are almost exactly the same as the solutions for distributing that program across multiple machines. The patterns really map well to these kinds of problems. On Tuesday, August 8, 2017 at 2:01:12 AM UTC-4, snmed wrote: > > Hi Gophers > > I stumbled over a nice and very interesting Blog entry "Go channels are > bad and you should feel bad > <http://www.jtolds.com/writing/2016/03/go-channels-are-bad-and-you-should-feel-bad/>" > > , I would like to hear some opinions about that article > from seasoned go developers. Because I just used go for a couple of months > for my private web projects and rarely get in touch with channels. > > By the way, that article is not a rant and the author likes go very much > as far as I can conclude from the article. > > Cheers snmed > -- 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. For more options, visit https://groups.google.com/d/optout.