This is the code that I am trying to write ->
total ,err := go buildRepository.CountBuildScreenshots(buildId, OrgId, userID)
if err!=nil {
fmt.Println(err)
}
Count Build Screenshots return an integer and an error.
My use case is that I have multiple builds for which I want to run this function. This function is computationally expensive and takes 5 seconds for computing for a single build. Hence I wanted to use wait Groups for the same.
for i := 0; i < len(builds); i++ {
buildId := builds[i].BuildId
buildRepository := NewBuildRepository(database.GetReadLTMSConn())
total ,err := go (buildRepository.CountBuildScreenshots(buildId, OrgId, userID))
if err!=nil {
fmt.Println(err)
}
(builds[i]).TotalScreenshots = total
}
I would wrap your function in a function that doesn't return anything but writes to a channel. Then you can read from that channel an wait for all results.
I am wrapping the loop in another goroutine to be able to close the channel after all are done writing to it.
type result struct {
Count int
Err error
}
func main() {
// the channel for the results
c := make(chan result)
// the top level goroutine waits for all
// spawned goroutines to be done and closes the channel
go func(c chan result) {
// waitgroup is used to wait
wg := &sync.WaitGroup{}
// kick of the long running functions concurrently
// in they own goroutine
for i := 0; i < 10; i++ {
wg.Add(1)
go func(c chan result) {
defer wg.Done()
total, err = count()
// write the results to the channel
c <- result{total, err}
}(c)
}
// wait until all are done
wg.Wait()
// important, close the channel
close(c)
}(c)
// range over the results as they are coming in
// until the channel is closed
for r := range c {
if r.Err != nil {
fmt.Println(r.Err)
} else {
fmt.Println(r.Count)
}
}
}
// simulate a longer running function
func count() (int, error) {
r := rand.Intn(10)
time.Sleep(time.Duration(r) * time.Second)
return 1, nil
}