Concurrency in Go

Errata for Concurrency in Go

Submit your own errata for this product.

The errata list is a list of errors and their corrections that were found after the product was released. If the error was corrected in a later version or reprint the date of the correction will be displayed in the column titled "Date Corrected".

The following errata were submitted by our customers and approved as valid errors by the author or editor.

Color Key: Serious Technical Mistake Minor Technical Mistake Language or formatting error Typo Question Note Update

Version Location Description Submitted By Date Submitted Date Corrected
Safari Books Online
Chapter 1
Under Live Lock section: Chapter 1, The order of the defered statements should be reversed

walk := func(walking *sync.WaitGroup, name string) { var out bytes.Buffer defer func() { fmt.Println(out.String()) }()// defer walking.Done()// These 2 defer statements should be reversed to print the result all the time. fmt.Fprintf(&out, "%v is trying to scoot:", name) for i := 0; i < 5; i++ { 1 if tryLeft(&out) || tryRight(&out) { 2 return } } fmt.Fprintf(&out, "\n%v tosses her hands up in exasperation!", name) }

Sathish Gampa  Feb 13, 2018 
Safari Books Online
chap 1
5th paragraph before Deadlocks, Livelock, and Starvation section and last paragraph

1) The sentence, "Synchronizing access to the memory in this manner also has performance ramifactions." misspells ramifactions. 2) In the last paragraph, the sentence: "In the next chapter we’ll discuss the philosophy concurrency and why Go got so much right." drops the "of" between philosophy and concurrency.

Charles Sharp  Jul 27, 2017 
Page chap 3
Pool chapter

In Chapter 3 Pool section we got a feeling that objects keep in the pool are permanent. There is no mention of the temporary nature of the objects store in sync.Pool. Furthermore, there is even a sentence saying: "So why use a pool and not just instantiate objects as you go? Go has a garbage collector, so the instantiated objects will be automatically cleaned up" Which in my understanding convinces us that objects in the pool are permanent. The objects in the pool will be also automatically cleaned up without the notification. This is clearly stated in the sync Pool documentation. Does my feeling about Pool chapter is correct or am I misunderstood something

Note from the Author or Editor:
You are not incorrect; however, this is an implementation detail that should not affect proper usage of a `sync.Pool` whatsoever. I've introduced another paragraph to call this point out, and make a suggestion to use a `sync.Pool` when warranted. Thank you for your comment!

Tomasz Walaszek  Sep 13, 2017 
Safari Books Online
Timeouts and Cancellation paragraph

reallyLongCalculation function example is named reallyLongCaluclation in the text. Similarly is for longCalculation function.

Tomasz Walaszek  Oct 02, 2017 
Page xi
Acknowledgement section title

Acknowledgement becomes Acknowledgment.

Anonymous  Nov 29, 2017 
Safari Books Online
Chapter 3 Go’s Concurrency Building Blocks

1. "single upstream writeer" should be "single upstream writer" 2. "Here we create a buffered channel with a capacity of one." should be of capacity four (4) per the code. 3. Right before the conclusion of chapter 3 "correced faster", should be "corrected faster"

Vasko Zdravevski  Jul 05, 2017  Jul 18, 2017
Page 1
Chapter 4 -> Pipelines -> Best Practices for Constructing Pipelines.

The generator function takes in a variadic slice of integers, constructs a buffered channel of integers with a length equal to the incoming integer slice, This sentence may be incorrect, as in previous demo, it create a unbuffered channel other than a buffered one with following code. instStream := make(chan int)

Note from the Author or Editor:
Thank you! I have corrected the code rather than the sentence. I had intended for the `generator` function to use a buffered channel, but this must have gotten lost somewhere along the way.

Haoran Feng  Oct 08, 2017 
Page 16
2nd paragraph

Should the start of the paragraph, "When we discussed livelocks", be changed to "When we discussed deadlocks" instead?

Note from the Author or Editor:
Thank you for the question! I do intend to discuss livelocks here; however, you are correct to point out that deadlocks are also a form of starvation. This paragraph is less about enumerating all the types of starvation, and more about contrasting livelocks with the broader classification of starvation.

Anonymous  Oct 20, 2017 
Page 28
3rd paragraph

The problem is with the phrase "perl programmers would probably disagree!" -- Perl should be capitalized, as it is the name of the language. Lowercase "perl" is the name of the interpreter.

Note from the Author or Editor:
I see we have a Perl fan in the vicinity :) Thank you!

Dmitri Tikhonov  Oct 13, 2017 
Page 38
2nd paragraph from the bottom

The sentence "What makes goroutines unique to Go are their deep integration with Go's runtime." is grammatically incorrect. Since "integration" is singular, "is" must be used instead of "are:" "What makes goroutines unique to Go is their deep integration with Go's runtime."

Dmitri Tikhonov  Oct 15, 2017 
Page 40
3rd paragraph

In the very first line of the 3rd paragraph on p.40, there's a phrase that "the rest of the rest of the main function for simplicity...". It seems the doubled "the rest of" is typo.

Yoshi Yamaguchi  Dec 26, 2017 
Page 55
code sample

In the increment and decrement section are for loops. They should run from i = 0 to i <= 5, but with the i-- this would end up in two endless loops.This should be a i++.

mike e.  Apr 23, 2017  Jul 18, 2017
Page 59
4th para (2nd of Pool section)

There is an extra 'a' in the first sentence: At a high level, a the pool pattern...

Gavin Massingham  Aug 13, 2017 
Page 63
1st paragraph

The first sentence has extra "like": "Looks like like roughly 1E9 ns/op."

Yoshi Yamaguchi  Jan 05, 2018 
Page 73
Code annotation 3

The annotation states that the buffered channel has a capacity of one, but the code actually shows a capacity of four.

Oliver Butterfield  Nov 13, 2017 
Page 73
Last paragraph

The final paragraph reads "... our anonymous goroutine is able to place all five of its results on the intstream and exit before the main goroutine pulls even one result off:" This statement is misleading because the section is trying to demonstrate how a buffered channel works i.e. by blocking the producer when the channel is full. In the code, the channel has been set to a capacity of 4 (which is 1 less that the number of items being produced). The description above implies that with a channel of capacity 4, that somehow 5 items can be placed. An additional line of code that printed "Item # sent" would be more useful because it should show that the 5th item cannot be placed on the channel.

Note from the Author or Editor:
Thank you for catching this! Here, I am attempting to demonstrate how you can write all input to a buffered channel before anything is read; I had an off-by-one error in that I'm looping too many times. I've reduced the guard to 4 to achieve the desired result.

Alex Howle  Apr 03, 2018 
Page 82
Code Sample

I would think that the workCounter/Sleep operations would be placed inside the default case to simulate work to be done while waiting for the done channel to close as opposed to being part of the for loop.

Note from the Author or Editor:
Thank you for the comment! Semantically, the code as written and your suggestion are the same. As it is written, the `select` statement will fall through to the `default` clause and then exit and the remainder of the loop body will execute. It comes down to preference, and I like to limit indentation where possible, so I enjoy writing it as part of the loop.

Austin  Mar 14, 2018 
Page 102
4th paragraph

In the sentence, "we can pass add and multiple around...", the monospaced word "multiple" must be the function name mentioned in the previous sample code and it should be "multiply".

Yoshi Yamaguchi  Jan 27, 2018 
Page 116
last paragraph

In the sentence "now that we have four goroutines", it says there are 4 goroutine in the sample shown above, it should be eight goroutines, as the number of goroutines should be the same as `runtime.NumCPU()`, which is eight. The previous paragraph also says "We now have eight goroutines..."

Note from the Author or Editor:
Oops! This is the consequence of writing portions on different machines which have a different number of cores.

Yoshi Yamaguchi  Feb 05, 2018 
Page 120
Code sample tee-channel

There seems to an error in the syntax for the return values. Printed: tee := func(done <-chan interface{}, in <-chan interface{},) (_, _ <-chan interface{}) { <-chan interface{}) { ... Correct syntax: tee := func(done <-chan interface{}, in <-chan interface{}) (_, _ <-chan interface{}) { ...

Tobias Mühlberger  Aug 28, 2017 
Page 125
Code sample

The printed version is `long := sleep(done, 4*time.Second, short)`, but should this be `long := sleep(done, 4*time.Second, buffer)` instead?

Anonymous  Jan 28, 2018 
Printed, PDF, ePub
Page 158
last paragraph

In the first sentence, "We've made some progress: `reallyLongCaluculation` is...", the function name has typo. It is `reallyLongCalculation` (extra 'u' exists between 'l' and 'c' in 'Calculation')

Yoshi Yamaguchi  Mar 03, 2018 
Printed, PDF, ePub, Mobi
Page 159
5th paragraph

In the source snippet before the 5th paragraph, the function name is `wrietTallyToState`. However, in the 5th paragraph, it's written like " to `writeToState`". I grepped `writeToState` in chapter 5, the line is the only place where `writeToState` is mentioned. I'm not sure the original intention for the function name, these 2 should be consistent.

Note from the Author or Editor:
Thanks, corrected.

Yoshi Yamaguchi  Mar 05, 2018 
Printed, PDF, ePub, Mobi
Page 172
the 2nd last paragraph

In the sentence "the goroutines will sleep for a random amount of time between one and six nanoseconds to simulate load", the order of sleeping duration is "nanosecond", in the example code, the duration is set in "second" order as the following: simulatedLoadTime := time.Duration(1+rand.Intn(5))*time.Second

Yoshi Yamaguchi  Mar 11, 2018 
Printed, PDF, ePub, Mobi
Page 179
The last paragraph

In the sentence "Later this will help stress our `APIClient` and exercise our rate limiter", though the variable "APIClient" is mentioned, it doesn't come up in the source code samples in the book. I think it should be "APIConnection". I grepped the whole text in the book and I only found 2 lines where "APIClient" shows up, both are not source code snippets.

Yoshi Yamaguchi  Mar 17, 2018 
Printed, PDF, ePub, Mobi
Page 181
6th paragraph

`rates` package should be `rate` package. (no 's')

Yoshi Yamaguchi  Mar 18, 2018