你可以通过使用Go语言中的并发来编辑你的代码。

huangapple go评论96阅读模式
英文:

How can I edit my code to concurrency using in Go?

问题

我有一个名为getIPSetInfo的函数,它根据IpsetInfo数组中的元素数量进行多次HTTP请求。我该如何重新设计我的函数以使用多线程?我希望循环中的所有查询可以并行执行。

type IpsetInfo struct {
    OrgRef               ObjDesc  `json:"orgRef"`
    EdgeGatewayRef       ObjDesc  `json:"edgeGatewayRef"`
    OwnerRef             ObjDesc  `json:"ownerRef"`
    NetworkProviderScope string   `json:"networkProviderScope"`
    Status               string   `json:"status"`
    Id                   string   `json:"id"`
    Name                 string   `json:"name"`
    Description          string   `json:"description"`
    Type                 string   `json:"type"`
    IpAddresses          []string `json:"ipaddresses"`
}

func getIPSetInfo(ipsetIds []string) []IpsetInfo {
    var result []IpsetInfo
    var wg sync.WaitGroup
    var mu sync.Mutex

    for i := range ipsetIds {
        wg.Add(1)
        go func(id string) {
            defer wg.Done()

            url := "https://api-cloud-platform.com/cloudapi/1.0.0/firewallGroups/" + id
            _, body := httpGet(url, map[string]string{
                "Authorization": "Bearer " + accessToken,
            })

            var x IpsetInfo
            json.Unmarshal([]byte(body), &x)

            mu.Lock()
            result = append(result, x)
            mu.Unlock()
        }(ipsetIds[i])
    }

    wg.Wait()
    return result
}

func main() {
    ipsetIds := getIPSetIDs()
    IPSets := getIPSetInfo(ipsetIds)

    // 下面的Terraform模板将从模板中创建
    tmpl, err := template.ParseFiles("ipsets.template")
    if err != nil {
        log.Fatal(err)
    }

    f, err := os.Create("result.tf")
    if err != nil {
        log.Println("create file: ", err)
        return
    }

    err = tmpl.Execute(f, IPSets)
    if err != nil {
        log.Print("execute: ", err)
        return
    }

    f.Close()
}

在重新设计的getIPSetInfo函数中,我使用了sync.WaitGroupsync.Mutex来实现并行执行HTTP请求,并确保结果的安全访问。每个循环迭代都会启动一个goroutine来执行HTTP请求,并将结果添加到result切片中。sync.WaitGroup用于等待所有goroutine完成,而sync.Mutex用于保护result切片的并发访问。

英文:

I have a function getIPSetInfo that makes HTTP requests as many times as there are elements in IpsetInfo array.
How can I redesign my function to use multithreading?
I need all those queries in loop to be done in parallel.

type IpsetInfo struct {
OrgRef               ObjDesc  `json:"orgRef"`
EdgeGatewayRef       ObjDesc  `json:"edgeGatewayRef"`
OwnerRef             ObjDesc  `json:"ownerRef"`
NetworkProviderScope string   `json:"networkProviderScope"`
Status               string   `json:"status"`
Id                   string   `json:"id"`
Name                 string   `json:"name"`
Description          string   `json:"description"`
Type                 string   `json:"type"`
IpAddresses          []string `json:"ipaddresses"`
}
func getIPSetInfo(ipsetIds []string) []IpsetInfo {
var result []IpsetInfo
for i := range ipsetIds {
url := "https://api-cloud-platform.com/cloudapi/1.0.0/firewallGroups/" + ipsetIds[i]
_, body := httpGet(url, map[string]string{
"Authorization": "Bearer " + accessToken,
})
var x IpsetInfo
json.Unmarshal([]byte(body), &x)
result = append(result, x)
}
return result
} 
func main() {
ipsetIds := getIPSetIDs()
IPSets := getIPSetInfo(ipsetIds)
// Below terraform manifest will be created from template 
tmpl, err := template.ParseFiles("ipsets.template")
if err != nil {
log.Fatal(err)
}
f, err := os.Create("result.tf")
if err != nil {
log.Println("create file: ", err)
return
}
err = tmpl.Execute(f, IPSets)
if err != nil {
log.Print("execute: ", err)
return
}
f.Close()
}

答案1

得分: 3

也许这可以帮助你:

func getIPSetInfo(ipsetIds []string) []IpsetInfo {
    mu := &sync.Mutex{}
    var wg sync.WaitGroup
    
    var result []IpsetInfo
    
    call := func(val string){
        defer wg.Done()
        
        url := "https://api-cloud-platform.com/cloudapi/1.0.0/firewallGroups/" + val
        _, body := httpGet(url, map[string]string{
            "Authorization": "Bearer " + accessToken,
        })
        var x IpsetInfo
        json.Unmarshal([]byte(body), &x)
        
        mu.Lock()
        defer mu.Unlock()
        
        result = append(result, x)
    }
    
    for _, val := range ipsetIds {
        wg.Add(1)
        go call(val)
    }

    wg.Wait()
    return result
} 

希望对你有帮助!

英文:

Maybe this could help

func getIPSetInfo(ipsetIds []string) []IpsetInfo {
mu := &sync.Mutex{}
var wg sync.WaitGroup
var result []IpsetInfo
call := func(val string){
defer wg.Done()
url := "https://api-cloud-platform.com/cloudapi/1.0.0/firewallGroups/" + val
_, body := httpGet(url, map[string]string{
"Authorization": "Bearer " + accessToken,
})
var x IpsetInfo
json.Unmarshal([]byte(body), &x)
mu.Lock()
defer mu.Unlock()
result = append(result, x)
}
for _, val := range ipsetIds {
wg.Add(1)
go call(val)
}
wg.Wait()
return result
} 

huangapple
  • 本文由 发表于 2022年7月1日 18:00:57
  • 转载请务必保留本文链接:https://go.coder-hub.com/72827584.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定