<p>I know there are multiple different solutions to do what I am looking for, but I am looking for a/the proper way to perform some requests in parallel. I am new to Go but it feels cumbersome what I am doing at the moment.</p>

<p><strong>Use case:</strong></p>

<p>I need to query 4 different REST endpoints (kubernetes client requests) in parallel. Once I got all these 4 results I need to do some processing.</p>

<p><strong>My problem:</strong></p>

<p>I know I need to use go routines for that, but what's the best way to collect the results. What I am doing at the moment (see code sample below) is probably very cumbersome, but I am not sure what else I could do to improve the code.</p>

<p><strong>Code:</strong></p>

<p>This code is the easiest to understand but I don't want to perform the requests in sequence:</p>

<pre><code>// Get node resource usage metrics
nodeMetricsList, err := c.kubernetesClient.NodeMetricses()
if err != nil {
    log.Warn("Failed to get node usage list from Kubernetes", err)
    return err
}

// Get pod resource usage metrics
podMetricsList, err := c.kubernetesClient.PodMetricses()
if err != nil {
    log.Warn("Failed to get pod usage list from Kubernetes", err)
    return err
}
</code></pre>

<p>This is how I would run the requests in parallel. This makes the code so much less readable and it feels very cumbersome to implement too:</p>

<pre><code>var nodeMetricsList *v1beta1.NodeMetricsList
var nodeMetricsListError error
var podMetricsList *v1beta1.PodMetricsList
var podMetricsListError error

go func() {
    nodeMetricsList, nodeMetricsListError = c.kubernetesClient.NodeMetricses()
}()
if nodeMetricsListError != nil {
    log.Warn("Failed to get podList from Kubernetes", err)
    return err
}

// Get pod resource usage metrics
go func() {
    podMetricsList, podMetricsListError = c.kubernetesClient.PodMetricses()
}()
if podMetricsListError != nil {
    log.Warn("Failed to get pod usage list from Kubernetes", err)
    return err
}
</code></pre>

<p>What's the proper way to perform the requests in my given example in parallel?</p>

kentor
<p>Your code has 2 race conditions, and likely will never correctly report an error.</p>

<p>You need to wait for the goroutines to complete before you can read the values they operate on, which is easily done with a <code>sync.WaitGroup</code> like so:</p>

<pre><code>var nodeMetricsList *v1beta1.NodeMetricsList
var podMetricsList *v1beta1.PodMetricsList
var nodeMetricsListError, podMetricsListError error
var wg sync.WaitGroup

// Get node resource usage metrics
wg.Add(1)
go func() {
    defer wg.Done()
    nodeMetricsList, nodeMetricsListError = c.kubernetesClient.NodeMetricses()
}()

// Get pod resource usage metrics
wg.Add(1)
go func() {
    defer wg.Done()
    podMetricsList, podMetricsListError = c.kubernetesClient.PodMetricses()
}()

wg.Wait()
if nodeMetricsListError != nil {
    log.Warn("Failed to get podList from Kubernetes", err)
    return err
}
if podMetricsListError != nil {
    log.Warn("Failed to get pod usage list from Kubernetes", err)
    return err
}

fmt.Println("Hello, playground")
</code></pre>
