What I'm trying to do: I'm trying to understand/build a go pipeline with three stages. Stage 1 writes to channel A. Stage 2 has multiple go routines. Each go routine reads from Channel A, performs some operation and writes result to Channel Bn(Channel B1, B2..Bn). Stage 3 has creates n(=total number of Channels in Stage 2) go routines, each go routine reads from one Channel from stage 2. It is based on bounded parallelism described in https://blog.golang.org/pipelines
Issue: The pipeline works fine as expected, the operation is distributed among go routines. But when I did an escape analysis and found that channel parameter sent from one stage to another is reported as "leaking param".
Code snippet: For simplicity, I'm posting code that shows stage 1 channel creation, and a stage 2 that prints value read from stage channel 1.
package main
import "fmt"
func createStageOne(numOfJobs int) <-chan int {
stageOneChannel := make(chan int)
go func(nJobs int) {
for i := 0; i < nJobs; i++ {
stageOneChannel <- i
}
close(stageOneChannel)
}(numOfJobs)
return stageOneChannel
} // stageOneChannel closes and go routine exits once nJobs are completed
func createStageTwo(in <-chan int, completionFlag chan struct{}) {
go func() {
for n := range in {
fmt.Println("Received from stage 1 channel ", n)
}
completionFlag <- struct{}{}
}()
}// Comes out of for loop when stage 1 channel closes and go routine also exits
func main() {
numOfJobs := 10
stageOneChannel := createStageOne(numOfJobs)
done := make(chan struct{})
createStageTwo(stageOneChannel, done)
<-done
}
Here is the escape analysis result
$ go build -gcflags "-m -l"
# concurrentHTTP/stackoverflow
./pipeline.go:7:5: func literal escapes to heap
./pipeline.go:7:5: func literal escapes to heap
./pipeline.go:6:25: make(chan int) escapes to heap
./pipeline.go:17:5: func literal escapes to heap
./pipeline.go:17:5: func literal escapes to heap
./pipeline.go:16:21: leaking param: in
./pipeline.go:16:36: leaking param: completionFlag
./pipeline.go:19:16: "Received from stage 1 channel " escapes to heap
./pipeline.go:19:16: n escapes to heap
./pipeline.go:19:15: createStageTwo.func1 ... argument does not escape
./pipeline.go:29:14: make(chan struct {}) escapes to heap
Why is escape analysis reporting leaking param on in and completionFlag flag?