Skip to content

Instantly share code, notes, and snippets.

@twotwotwo
Last active February 27, 2022 14:58
Show Gist options
  • Select an option

  • Save twotwotwo/fe5c5020a2bb5f7f0ce3 to your computer and use it in GitHub Desktop.

Select an option

Save twotwotwo/fe5c5020a2bb5f7f0ce3 to your computer and use it in GitHub Desktop.

Revisions

  1. twotwotwo revised this gist Mar 16, 2016. 1 changed file with 1 addition and 1 deletion.
    2 changes: 1 addition & 1 deletion gistfile1.md
    Original file line number Diff line number Diff line change
    @@ -12,7 +12,7 @@ Spec sections on channels (https://golang.org/ref/spec#Channel_types), send (htt

    Running a concurrent test under the race detector is a useful check. Helps to get a little familiarity with the sync package: https://godoc.org/sync. Introductory stuff mostly emphasizes channels, because that's what's specific to Go, but when your goal isn't communication you should be aware of, e.g. `sync.WaitGroup` to wait for workers to finish, `sync.Mutex` or `sync.RWLock` when you're really just sharing data, `sync.Once` during init, `sync/atomic` in the somewhat rarer cases you have global state you can update atomically.

    For performance, if you have tiny tasks (where microseconds of overhead per task matters), using buffers or batching them can help. [I ran into this in some parallel sorting code (and dealt by only sending sorts of 128+ items to other sort workers).](https://github.com/twotwotwo/sorts/blob/master/parallel.go) Standard library source also has some concurrency management--it's usually readable code, though sometimes you have to understand what it's doing to understand what the concurrency primitives are there for.
    For performance, if you have tiny tasks (where microseconds of overhead per task matters), using buffers or batching them can help; it's rarely an issue when network or DB operations are involved, but can be on small pure-computation tasks. [I ran into this in some parallel sorting code (and dealt by only sending sorts of 128+ items to other sort workers).](https://github.com/twotwotwo/sorts/blob/master/parallel.go) Standard library source also has some concurrency management--it's usually readable code, though sometimes you have to understand what it's doing to understand what the concurrency primitives are there for.

    I hate to say this but in learning this stuff there's often a certain amount of trial and error, in getting to elegance if not to correctness; I think my first largish Go program accidentally implemented a lock using a buffered channel. It may help to open a text file somewhere to sketch out your goroutines, channels, etc. (separated from all the other details of your app), why you need each, and see if you can remove anything or change something to a better-fitting primitive.

  2. twotwotwo revised this gist Mar 16, 2016. 1 changed file with 2 additions and 2 deletions.
    4 changes: 2 additions & 2 deletions gistfile1.md
    Original file line number Diff line number Diff line change
    @@ -12,9 +12,9 @@ Spec sections on channels (https://golang.org/ref/spec#Channel_types), send (htt

    Running a concurrent test under the race detector is a useful check. Helps to get a little familiarity with the sync package: https://godoc.org/sync. Introductory stuff mostly emphasizes channels, because that's what's specific to Go, but when your goal isn't communication you should be aware of, e.g. `sync.WaitGroup` to wait for workers to finish, `sync.Mutex` or `sync.RWLock` when you're really just sharing data, `sync.Once` during init, `sync/atomic` in the somewhat rarer cases you have global state you can update atomically.

    For performance, if you have tiny tasks (where microseconds of overhead per task matters), using buffers or batching them can help.
    For performance, if you have tiny tasks (where microseconds of overhead per task matters), using buffers or batching them can help. [I ran into this in some parallel sorting code (and dealt by only sending sorts of 128+ items to other sort workers).](https://github.com/twotwotwo/sorts/blob/master/parallel.go) Standard library source also has some concurrency management--it's usually readable code, though sometimes you have to understand what it's doing to understand what the concurrency primitives are there for.

    I hate to say this but in learning this stuff there's often a certain amount of trial and error, in getting to elegance if not to correctness; I think my first largish Go program accidentally implemented a lock using a buffered channel. It may help to open a text file somewhere to sketch out your goroutines, channels, etc, why you need each, and see if you can remove anything or change something to a better-fitting primitive.
    I hate to say this but in learning this stuff there's often a certain amount of trial and error, in getting to elegance if not to correctness; I think my first largish Go program accidentally implemented a lock using a buffered channel. It may help to open a text file somewhere to sketch out your goroutines, channels, etc. (separated from all the other details of your app), why you need each, and see if you can remove anything or change something to a better-fitting primitive.

    Couple third-party things I haven't actually looked at:
    * https://blog.gopheracademy.com/composable-pipelines-pattern/
  3. twotwotwo revised this gist Mar 16, 2016. 1 changed file with 4 additions and 2 deletions.
    6 changes: 4 additions & 2 deletions gistfile1.md
    Original file line number Diff line number Diff line change
    @@ -12,8 +12,10 @@ Spec sections on channels (https://golang.org/ref/spec#Channel_types), send (htt

    Running a concurrent test under the race detector is a useful check. Helps to get a little familiarity with the sync package: https://godoc.org/sync. Introductory stuff mostly emphasizes channels, because that's what's specific to Go, but when your goal isn't communication you should be aware of, e.g. `sync.WaitGroup` to wait for workers to finish, `sync.Mutex` or `sync.RWLock` when you're really just sharing data, `sync.Once` during init, `sync/atomic` in the somewhat rarer cases you have global state you can update atomically.

    For performance, if you have tiny tasks (where microseconds of overhead per task matters), using buffers or batching them can help.

    I hate to say this but in learning this stuff there's often a certain amount of trial and error, in getting to elegance if not to correctness; I think my first largish Go program accidentally implemented a lock using a buffered channel. It may help to open a text file somewhere to sketch out your goroutines, channels, etc, why you need each, and see if you can remove anything or change something to a better-fitting primitive.

    Couple third-party things I haven't actually looked at:
    https://blog.gopheracademy.com/composable-pipelines-pattern/
    https://gobyexample.com/channels and the next few pages in the series
    * https://blog.gopheracademy.com/composable-pipelines-pattern/
    * https://gobyexample.com/channels and the next few pages in the series
  4. twotwotwo revised this gist Mar 16, 2016. 1 changed file with 8 additions and 8 deletions.
    16 changes: 8 additions & 8 deletions gistfile1.md
    Original file line number Diff line number Diff line change
    @@ -1,14 +1,14 @@
    https://golang.org/doc/effective_go.html#concurrency
    https://talks.golang.org/2012/waza.slide
    https://blog.golang.org/pipelines
    * https://golang.org/doc/effective_go.html#concurrency
    * https://talks.golang.org/2012/waza.slide
    * https://blog.golang.org/pipelines

    Spec sections on channels (https://golang.org/ref/spec#Channel_types), send (https://golang.org/ref/spec#Send_statements), receive (https://golang.org/ref/spec#Receive_operator), select (https://golang.org/ref/spec#Select_statements), close (https://golang.org/ref/spec#Close). The memory model is described at https://golang.org/ref/mem.

    http://blog.golang.org/go-concurrency-patterns-timing-out-and
    http://blog.golang.org/context
    http://blog.golang.org/race-detector
    http://blog.golang.org/concurrency-is-not-parallelism
    http://blog.golang.org/advanced-go-concurrency-patterns
    * http://blog.golang.org/go-concurrency-patterns-timing-out-and
    * http://blog.golang.org/context
    * http://blog.golang.org/race-detector
    * http://blog.golang.org/concurrency-is-not-parallelism
    * http://blog.golang.org/advanced-go-concurrency-patterns

    Running a concurrent test under the race detector is a useful check. Helps to get a little familiarity with the sync package: https://godoc.org/sync. Introductory stuff mostly emphasizes channels, because that's what's specific to Go, but when your goal isn't communication you should be aware of, e.g. `sync.WaitGroup` to wait for workers to finish, `sync.Mutex` or `sync.RWLock` when you're really just sharing data, `sync.Once` during init, `sync/atomic` in the somewhat rarer cases you have global state you can update atomically.

  5. twotwotwo renamed this gist Mar 16, 2016. 1 changed file with 0 additions and 0 deletions.
    File renamed without changes.
  6. twotwotwo created this gist Mar 16, 2016.
    19 changes: 19 additions & 0 deletions gistfile1.txt
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,19 @@
    https://golang.org/doc/effective_go.html#concurrency
    https://talks.golang.org/2012/waza.slide
    https://blog.golang.org/pipelines

    Spec sections on channels (https://golang.org/ref/spec#Channel_types), send (https://golang.org/ref/spec#Send_statements), receive (https://golang.org/ref/spec#Receive_operator), select (https://golang.org/ref/spec#Select_statements), close (https://golang.org/ref/spec#Close). The memory model is described at https://golang.org/ref/mem.

    http://blog.golang.org/go-concurrency-patterns-timing-out-and
    http://blog.golang.org/context
    http://blog.golang.org/race-detector
    http://blog.golang.org/concurrency-is-not-parallelism
    http://blog.golang.org/advanced-go-concurrency-patterns

    Running a concurrent test under the race detector is a useful check. Helps to get a little familiarity with the sync package: https://godoc.org/sync. Introductory stuff mostly emphasizes channels, because that's what's specific to Go, but when your goal isn't communication you should be aware of, e.g. `sync.WaitGroup` to wait for workers to finish, `sync.Mutex` or `sync.RWLock` when you're really just sharing data, `sync.Once` during init, `sync/atomic` in the somewhat rarer cases you have global state you can update atomically.

    I hate to say this but in learning this stuff there's often a certain amount of trial and error, in getting to elegance if not to correctness; I think my first largish Go program accidentally implemented a lock using a buffered channel. It may help to open a text file somewhere to sketch out your goroutines, channels, etc, why you need each, and see if you can remove anything or change something to a better-fitting primitive.

    Couple third-party things I haven't actually looked at:
    https://blog.gopheracademy.com/composable-pipelines-pattern/
    https://gobyexample.com/channels and the next few pages in the series