Простой способ ограничения параллелизма в Go


У меня есть CSV-файл с ~10k URL-адресами, которые мне нужны для HTTP get. Каков самый простой способ ограничить параллелизм подпрограмм Go не более чем 16 одновременно?

func getUrl(url string) {
    request := gorequest.New()
    resp, body, errs := request.Get(each[1]).End()
    _ = resp
    _ = body
    _ = errs
}

func main() {

    csvfile, err := os.Open("urls.csv")
    defer csvfile.Close()
    reader := csv.NewReader(csvfile)
    reader.FieldsPerRecord = -1 
    rawCSVdata, err := reader.ReadAll()

    completed := 0
    for _, each := range rawCSVdata {
        go getUrl(each[1])
        completed++
    }
}
1 5

1 ответ:

Модель производитель-потребитель:

package main

import (
    "encoding/csv"
    "os"
    "sync"

    "github.com/parnurzeal/gorequest"
)

const workersCount = 16

func getUrlWorker(urlChan chan string) {
    for url := range urlChan {
        request := gorequest.New()
        resp, body, errs := request.Get(url).End()
        _ = resp
        _ = body
        _ = errs
    }
}

func main() {
    csvfile, err := os.Open("urls.csv")
    if err != nil {
        panic(err)
    }
    defer csvfile.Close()

    reader := csv.NewReader(csvfile)
    reader.FieldsPerRecord = -1
    rawCSVdata, err := reader.ReadAll()

    var wg sync.WaitGroup
    urlChan := make(chan string)

    wg.Add(workersCount)

    for i := 0; i < workersCount; i++ {
        go func() {
            getUrlWorker(urlChan)
            wg.Done()
        }()
    }

    completed := 0
    for _, each := range rawCSVdata {
        urlChan <- each[1]
        completed++
    }
    close(urlChan)

    wg.Wait()
}