I'm still experiencing how to make best use of channels.
I have 5 outbound service calls (take ~2 min to return), and each gives me a pair of return values.
e.g. func serviceCall()(T, error)
I want to make them concurrent, but I find the code very lengthy.
Basically, I have to create 5 channels, 5 structs to hold the return value.
I wrote a simple example to express the scenario, I want to know what is the pattern for this scenario, how I can make this code better.
package main
import (
"fmt"
"math/rand"
"time"
"log"
)
// goal: run multiple functions concurrently and process the results.
func main() {
now := time.Now()
// method1
type res1 struct {
news string
err error
}
type res2 struct {
n int
err error
}
ch1 := make(chan *res1)
ch2 := make(chan *res2)
go func() {
var res res1
res.news, res.err = news1()
ch1 <- &res
}()
go func() {
var res res2
res.n, res.err = news2()
ch2 <- &res
}()
one := <-ch1
if one.err != nil {
log.Fatal(one.err)
}
fmt.Println("news1: ", one.news)
two := <-ch2
if two.err != nil {
log.Fatal(two.err)
}
fmt.Println("news2: ", two.n)
fmt.Println("time elapsed: ", time.Since(now))
}
// first sleeps 5 seconds and returns random number or error.
func news1() (string, error) {
time.Sleep(time.Second * 5)
return "new1 is here.", nil
}
// second sleeps random seconds and returns random number or error.
func news2() (int, error) {
n := rand.Intn(20)
time.Sleep(time.Duration(n) * time.Second)
return n, nil
}