I have a CSV file with ~10k URLs I need to HTTP get. What is the simplest way to limit the concurrency of Go routines to no more than 16 at a time?
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++
}
}
In Go, concurrency works through the use of in-built functions known as Goroutines. Goroutines are functions, unique to Go, that run at the same time alongside other code or programs. They're not OS threads, though, they may be considered lightweight threads.
Concurrency in Golang is cheap and easy. Goroutines are cheap, lightweight threads. Channels, are the conduits that allow for communication between goroutines. Communicating Sequential Processes, or CSP for short, is used to describe how systems that feature multiple concurrent models should interact with one another.
The key to achieving Golang concurrency is using Goroutines – lightweight, low-cost methods or functions that can run concurrently with other methods and functions.
Following a model proposed by the renowned computer scientist Tony Hoare, Go uses the concurrency model called Communicating Sequential Processes (CSP).
A producer-consumers pattern:
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()
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With