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

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

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

问题

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

  1. type IpsetInfo struct {
  2. OrgRef ObjDesc `json:"orgRef"`
  3. EdgeGatewayRef ObjDesc `json:"edgeGatewayRef"`
  4. OwnerRef ObjDesc `json:"ownerRef"`
  5. NetworkProviderScope string `json:"networkProviderScope"`
  6. Status string `json:"status"`
  7. Id string `json:"id"`
  8. Name string `json:"name"`
  9. Description string `json:"description"`
  10. Type string `json:"type"`
  11. IpAddresses []string `json:"ipaddresses"`
  12. }
  13. func getIPSetInfo(ipsetIds []string) []IpsetInfo {
  14. var result []IpsetInfo
  15. var wg sync.WaitGroup
  16. var mu sync.Mutex
  17. for i := range ipsetIds {
  18. wg.Add(1)
  19. go func(id string) {
  20. defer wg.Done()
  21. url := "https://api-cloud-platform.com/cloudapi/1.0.0/firewallGroups/" + id
  22. _, body := httpGet(url, map[string]string{
  23. "Authorization": "Bearer " + accessToken,
  24. })
  25. var x IpsetInfo
  26. json.Unmarshal([]byte(body), &x)
  27. mu.Lock()
  28. result = append(result, x)
  29. mu.Unlock()
  30. }(ipsetIds[i])
  31. }
  32. wg.Wait()
  33. return result
  34. }
  35. func main() {
  36. ipsetIds := getIPSetIDs()
  37. IPSets := getIPSetInfo(ipsetIds)
  38. // 下面的Terraform模板将从模板中创建
  39. tmpl, err := template.ParseFiles("ipsets.template")
  40. if err != nil {
  41. log.Fatal(err)
  42. }
  43. f, err := os.Create("result.tf")
  44. if err != nil {
  45. log.Println("create file: ", err)
  46. return
  47. }
  48. err = tmpl.Execute(f, IPSets)
  49. if err != nil {
  50. log.Print("execute: ", err)
  51. return
  52. }
  53. f.Close()
  54. }

在重新设计的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.

  1. type IpsetInfo struct {
  2. OrgRef ObjDesc `json:"orgRef"`
  3. EdgeGatewayRef ObjDesc `json:"edgeGatewayRef"`
  4. OwnerRef ObjDesc `json:"ownerRef"`
  5. NetworkProviderScope string `json:"networkProviderScope"`
  6. Status string `json:"status"`
  7. Id string `json:"id"`
  8. Name string `json:"name"`
  9. Description string `json:"description"`
  10. Type string `json:"type"`
  11. IpAddresses []string `json:"ipaddresses"`
  12. }
  13. func getIPSetInfo(ipsetIds []string) []IpsetInfo {
  14. var result []IpsetInfo
  15. for i := range ipsetIds {
  16. url := "https://api-cloud-platform.com/cloudapi/1.0.0/firewallGroups/" + ipsetIds[i]
  17. _, body := httpGet(url, map[string]string{
  18. "Authorization": "Bearer " + accessToken,
  19. })
  20. var x IpsetInfo
  21. json.Unmarshal([]byte(body), &x)
  22. result = append(result, x)
  23. }
  24. return result
  25. }
  26. func main() {
  27. ipsetIds := getIPSetIDs()
  28. IPSets := getIPSetInfo(ipsetIds)
  29. // Below terraform manifest will be created from template
  30. tmpl, err := template.ParseFiles("ipsets.template")
  31. if err != nil {
  32. log.Fatal(err)
  33. }
  34. f, err := os.Create("result.tf")
  35. if err != nil {
  36. log.Println("create file: ", err)
  37. return
  38. }
  39. err = tmpl.Execute(f, IPSets)
  40. if err != nil {
  41. log.Print("execute: ", err)
  42. return
  43. }
  44. f.Close()
  45. }

答案1

得分: 3

也许这可以帮助你:

  1. func getIPSetInfo(ipsetIds []string) []IpsetInfo {
  2. mu := &sync.Mutex{}
  3. var wg sync.WaitGroup
  4. var result []IpsetInfo
  5. call := func(val string){
  6. defer wg.Done()
  7. url := "https://api-cloud-platform.com/cloudapi/1.0.0/firewallGroups/" + val
  8. _, body := httpGet(url, map[string]string{
  9. "Authorization": "Bearer " + accessToken,
  10. })
  11. var x IpsetInfo
  12. json.Unmarshal([]byte(body), &x)
  13. mu.Lock()
  14. defer mu.Unlock()
  15. result = append(result, x)
  16. }
  17. for _, val := range ipsetIds {
  18. wg.Add(1)
  19. go call(val)
  20. }
  21. wg.Wait()
  22. return result
  23. }

希望对你有帮助!

英文:

Maybe this could help

  1. func getIPSetInfo(ipsetIds []string) []IpsetInfo {
  2. mu := &sync.Mutex{}
  3. var wg sync.WaitGroup
  4. var result []IpsetInfo
  5. call := func(val string){
  6. defer wg.Done()
  7. url := "https://api-cloud-platform.com/cloudapi/1.0.0/firewallGroups/" + val
  8. _, body := httpGet(url, map[string]string{
  9. "Authorization": "Bearer " + accessToken,
  10. })
  11. var x IpsetInfo
  12. json.Unmarshal([]byte(body), &x)
  13. mu.Lock()
  14. defer mu.Unlock()
  15. result = append(result, x)
  16. }
  17. for _, val := range ipsetIds {
  18. wg.Add(1)
  19. go call(val)
  20. }
  21. wg.Wait()
  22. return result
  23. }

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:

确定