dsplos5731 2019-02-21 20:54
浏览 86
已采纳

并行执行不同请求的正确方法

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.

Use case:

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.

My problem:

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.

Code:

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

// 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
}

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:

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
}

What's the proper way to perform the requests in my given example in parallel?

  • 写回答

1条回答 默认 最新

  • dongxiao_0528 2019-02-21 20:59
    关注

    Your code has 2 race conditions, and likely will never correctly report an error.

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

    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")
    
    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥15 孟德尔随机化怎样画共定位分析图
  • ¥18 模拟电路问题解答有偿速度
  • ¥15 CST仿真别人的模型结果仿真结果S参数完全不对
  • ¥15 误删注册表文件致win10无法开启
  • ¥15 请问在阿里云服务器中怎么利用数据库制作网站
  • ¥60 ESP32怎么烧录自启动程序
  • ¥50 html2canvas超出滚动条不显示
  • ¥15 java业务性能问题求解(sql,业务设计相关)
  • ¥15 52810 尾椎c三个a 写蓝牙地址
  • ¥15 elmos524.33 eeprom的读写问题