I have a goroutine inside a loop and I want to execute a goroutine for each item in ms.Entries concurrently but it's only running for the last item in the loop.
I've abstracted my example out of a larger program... https://play.golang.org/p/whUMQ3pjq81
package main
import (
"fmt"
"sync"
)
type MyStruct struct {
Entry *Entry
Entries *[]Entry
}
type Entry struct {
ID int
Name string
}
type Fn struct {
Res string
Err error
}
func main() {
e1 := Entry{ID: 1, Name: "First"}
e2 := Entry{ID: 2, Name: "Second"}
ms := &MyStruct{
Entries: &[]Entry{e1, e2},
}
fmt.Printf("MS: %+v
", ms)
var wg sync.WaitGroup
fnChan := make(chan *Fn)
go func() {
wg.Wait()
close(fnChan)
}()
var fns []func() (string, error)
fns = append(fns, ms.actionA)
fns = append(fns, ms.actionB)
for i, entry := range *ms.Entries {
fmt.Printf("%d: %+v
", i, entry)
ms.Entry = &entry
for j, fn := range fns {
fmt.Printf("fn loop %d
", j)
wg.Add(1)
go ms.process(&wg, fn, fnChan)
}
}
for d := range fnChan {
fmt.Printf("fnchan: %+v
", d)
}
}
func (m *MyStruct) actionA() (string, error) {
fmt.Println("actionA")
fmt.Printf("Entry: %s
", m.Entry.Name)
return "actionA done", nil
}
func (m *MyStruct) actionB() (string, error) {
fmt.Println("actionB")
fmt.Printf("Entry: %s
", m.Entry.Name)
return "actionB done", nil
}
func (m *MyStruct) process(wg *sync.WaitGroup, fn func() (string, error), fnChan chan<- *Fn) {
fmt.Println("processing")
var err error
defer wg.Done()
res, err := fn()
if err != nil {
fnChan <- &Fn{Err: err}
return
}
fnChan <- &Fn{Res: res}
}