content/blog/pipelines: fix explicit cancellation example The output goroutine in merge had an empty <-done case body, so receiving a cancellation signal would silently fall through to the next iteration of the for-range loop. The goroutine kept trying to forward values from c instead of exiting, leaving senders blocked when only one done value was available. Add a labeled break so receiving from done exits both the select and the outer for, mirroring the return statement used in the close example (sqdone3.go). Also bump gen(2, 3) to gen(2, 3, 5) so the counting cancellation example actually exercises both done sends. With only two inputs, at most one sender ends up blocked, and the second cancellation is unused. Fixes golang/go#78277 Change-Id: I212bdb41e1337da26e8559bf1b676980b57de5a0 Reviewed-on: https://go-review.googlesource.com/c/website/+/765660 Reviewed-by: Sean Liao <sean@liao.dev> Reviewed-by: David Chase <drchase@google.com> Reviewed-by: Mark Freeman <markfreeman@google.com> Auto-Submit: Sean Liao <sean@liao.dev> LUCI-TryBot-Result: golang-scoped@luci-project-accounts.iam.gserviceaccount.com <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
diff --git a/_content/blog/pipelines/sqdone1.go b/_content/blog/pipelines/sqdone1.go index e77818a..16f3d45 100644 --- a/_content/blog/pipelines/sqdone1.go +++ b/_content/blog/pipelines/sqdone1.go
@@ -1,3 +1,4 @@ +//go:build OMIT // +build OMIT package main @@ -41,10 +42,12 @@ // copies values from c to out until c is closed or it receives a value // from done, then output calls wg.Done. output := func(c <-chan int) { + loop: for n := range c { select { case out <- n: case <-done: // HL + break loop // HL } } wg.Done() @@ -66,7 +69,7 @@ } func main() { - in := gen(2, 3) + in := gen(2, 3, 5) // Distribute the sq work across two goroutines that both read from in. c1 := sq(in) @@ -75,7 +78,7 @@ // Consume the first value from output. done := make(chan struct{}, 2) // HL out := merge(done, c1, c2) - fmt.Println(<-out) // 4 or 9 + fmt.Println(<-out) // 4, 9, or 25 // Tell the remaining senders we're leaving. done <- struct{}{} // HL