Hacker News new | past | comments | ask | show | jobs | submit login
Advanced Go Concurrency Patterns [video] (golang.org)
121 points by enneff on May 24, 2013 | hide | past | favorite | 15 comments



The talk is worth watching, but is based on a single big "trick" (but really language feature).

The key thing shown in this talk to unlock all the other cool patterns is that a nil channel blocks indefinitely in a select statement, meaning it is never selected. So you can set channels to nil in order to "turn off" certain code paths in a select. Example:

    var myChan chan int
    if someCondition {
      // Turn on case by setting the channel
      myChan = someChannel
    }

    select {
    case <-myChan:
      // Do a thing. Will never execute if myChan is nil.
    // ... etc.
    }


That's the main trick, but the other pattern there I really liked was the idea of pulling all mutable state into the function which was running as the goroutine (and manipulated by the for-select).

It's a lot like an object instance, responding to messages, changing internal state and emitting messages.

In fact, here is the same approach in SICP, where they start to model objects as messages passed to a closure with internal mutable state:

http://mitpress.mit.edu/sicp/full-text/book/book-Z-H-21.html...

[scroll down a bit for exercise 3.11, the "cond dispatch" is analagous to the "for-select" case dispatch, except of course that golang select handles concurrency.]

It's the old "objects are a poor man's closures"/"closures are a poor man's object" duality.


With this approach, you could pull a lot of state out of the structure, and move it into variables local to the goroutine. It is interesting how this approach moves Go a lot closer to Erlang-style actors.


Yes, it seems very close to actors but I guess that's not too surprising if you're trying to converge on "ways to do concurrency which don't suck" from different languages.


Can't pass up a select without showing a timeout. This was an "ah ha" moment for me and go:

    select {
    case <-myChan:
      // Do a thing
    case <- time.After(10 * time.Second):
      // default/error whatever
    }


You can also use time.Tickers to schedule events to occur every so often in a similar fashion.

     for now := range time.NewTicker(time.Minute).C {
       fmt.Printf("%s is the current time\n", now)
     }
In case you are unfamiliar, the range keyword, when used on a channel, is equivalent to:

     for {
       select {
       case now := <-time.NewTicker(time.Minute).C:
         fmt.Printf("%s is the current time\n", now)
       }
     }


No, it operates more like:

    ticker := time.NewTicker(time.Minute)
    for {
        now, ok := <-ticker.C
        if !ok {
            break
        }
        fmt.Printf("%s is the current time\n", now)
    }
Your two loops are superficially equivalent only because the ticker isn't going to close its channel. Plus, you're creating a new ticker on every iteration in your second example, and you don't need the select statement, because your only blocking on a single receive operation.

The range over a channel is especially useful for a channel that will be closed, so you can break from the loop.


On the second example, wouldn't it make sense to create the ticker outside of the for loop instead ?


Yep, that was my bad. I got distracted when writing the example and didn't think things through because I realized I had installed Go 1.1 for i386 on my laptop and not x86_64. Such is life when commenting at 6AM :P


Thanks for posting this. I'm going to be learning Go for a little side project and couldn't quite remember this mechanism.


Exactly what I've been looking for. The original presentation Pike gave was great as an intro, but I was looking for some more applications. Definitely looking forward to more material like this.

Also, I love the tongue-in-cheek reference to what I presume is Google Reader:

  Example: feed reader
  My favorite feed reader disappeared. I need a new one.
  Why not write one?
  Where do we start?


I can't even go past the first slide from my phone and tablet :/ apparently you need arrow keys to move to the next slides.....


You can also click on the edges of the page (works for me on a pc anyway)


Really interesting. Could someone explain how these features relate in a language like python or C? Do they have the same features, but are more complicated to implement or is the architecture not even there to support such?


Neither language has channels or selects baked in.

Python does have threadsafe queues in the standard library, which you can use to coordinate work between threads and processes.

C doesn't come with anything like this, but you can use a library like ZeroMQ. The main Go compilers are written in C, so clearly anything Go can do C can do too -- but it'll be more work.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: