Skip to content

Commit 604fe62

Browse files
authored
fix: quiiGH-740 Update concurrency example and code to go 1.22 (quii#823)
1 parent 2af1f37 commit 604fe62

File tree

4 files changed

+10
-60
lines changed

4 files changed

+10
-60
lines changed

concurrency.md

Lines changed: 3 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -241,56 +241,6 @@ func CheckWebsites(wc WebsiteChecker, urls []string) map[string]bool {
241241
}
242242
```
243243

244-
Now when we run the tests you get (or don't get - see above):
245-
246-
```sh
247-
--- FAIL: TestCheckWebsites (0.00s)
248-
CheckWebsites_test.go:31: Wanted map[http://google.com:true http://blog.gypsydave5.com:true waat://furhurterwe.geds:false], got map[waat://furhurterwe.geds:false]
249-
FAIL
250-
exit status 1
251-
FAIL github.com/gypsydave5/learn-go-with-tests/concurrency/v1 0.010s
252-
```
253-
254-
This isn't great - why only one result? We might try and fix this by increasing
255-
the time we wait - try it if you like. It won't work. The problem here is that
256-
the variable `url` is reused for each iteration of the `for` loop - it takes
257-
a new value from `urls` each time. But each of our goroutines have a reference
258-
to the `url` variable - they don't have their own independent copy. So they're
259-
_all_ writing the value that `url` has at the end of the iteration - the last
260-
url. Which is why the one result we have is the last url.
261-
262-
To fix this:
263-
264-
```go
265-
package concurrency
266-
267-
import (
268-
"time"
269-
)
270-
271-
type WebsiteChecker func(string) bool
272-
273-
func CheckWebsites(wc WebsiteChecker, urls []string) map[string]bool {
274-
results := make(map[string]bool)
275-
276-
for _, url := range urls {
277-
go func(u string) {
278-
results[u] = wc(u)
279-
}(url)
280-
}
281-
282-
time.Sleep(2 * time.Second)
283-
284-
return results
285-
}
286-
```
287-
288-
By giving each anonymous function a parameter for the url - `u` - and then
289-
calling the anonymous function with the `url` as the argument, we make sure that
290-
the value of `u` is fixed as the value of `url` for the iteration of the loop
291-
that we're launching the goroutine in. `u` is a copy of the value of `url`, and
292-
so can't be changed.
293-
294244
Now if you're lucky you'll get:
295245

296246
```sh
@@ -413,9 +363,9 @@ func CheckWebsites(wc WebsiteChecker, urls []string) map[string]bool {
413363
resultChannel := make(chan result)
414364

415365
for _, url := range urls {
416-
go func(u string) {
417-
resultChannel <- result{u, wc(u)}
418-
}(url)
366+
go func() {
367+
resultChannel <- result{url, wc(url)}
368+
}()
419369
}
420370

421371
for i := 0; i < len(urls); i++ {

concurrency/v2/check_websites.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,9 +13,9 @@ func CheckWebsites(wc WebsiteChecker, urls []string) map[string]bool {
1313
results := make(map[string]bool)
1414

1515
for _, url := range urls {
16-
go func(u string) {
17-
results[u] = wc(u)
18-
}(url)
16+
go func() {
17+
results[url] = wc(url)
18+
}()
1919
}
2020

2121
time.Sleep(2 * time.Second)

concurrency/v3/check_websites.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,9 +14,9 @@ func CheckWebsites(wc WebsiteChecker, urls []string) map[string]bool {
1414
resultChannel := make(chan result)
1515

1616
for _, url := range urls {
17-
go func(u string) {
18-
resultChannel <- result{u, wc(u)}
19-
}(url)
17+
go func() {
18+
resultChannel <- result{url, wc(url)}
19+
}()
2020
}
2121

2222
for i := 0; i < len(urls); i++ {

go.mod

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
module github.com/quii/learn-go-with-tests
22

3-
go 1.18
3+
go 1.22
44

55
require (
66
github.com/alecthomas/assert/v2 v2.2.2

0 commit comments

Comments
 (0)