Without semaphore, without limiter
package main
import (
"fmt"
"io/ioutil"
"net/http"
"sync"
)
const (
count = 200
baseUrl = "https://jsonplaceholder.typicode.com/todos"
)
func main() {
wg := sync.WaitGroup{}
wg.Add(count)
for i := 0; i < count; i++ {
go func(i int) {
defer wg.Done()
getData(i)
}(i)
}
wg.Wait()
}
func getData(index int) error {
url := fmt.Sprintf("%s/%d", baseUrl, index)
res, err := http.Get(url)
if err != nil {
return err
}
defer res.Body.Close()
body, err := ioutil.ReadAll(res.Body)
if err != nil {
return err
}
fmt.Println(runtime.NumGoroutine())
fmt.Println(index)
fmt.Println(string(body))
return nil
}
With channel like limiter
package main
import (
"fmt"
"io/ioutil"
"net/http"
"runtime"
"sync"
)
const (
count = 200
limiter = 10
baseUrl = "https://jsonplaceholder.typicode.com/todos"
)
func main() {
wg := sync.WaitGroup{}
sem := make(chan bool, limiter)
wg.Add(count)
for i := 0; i < count; i++ {
sem <- true
go func(i int) {
defer wg.Done()
defer func() { <-sem }()
getData(i)
}(i)
}
wg.Wait()
}
func getData(index int) error {
url := fmt.Sprintf("%s/%d", baseUrl, index)
res, err := http.Get(url)
if err != nil {
return err
}
defer res.Body.Close()
body, err := ioutil.ReadAll(res.Body)
if err != nil {
return err
}
fmt.Println(runtime.NumGoroutine())
fmt.Println(index)
fmt.Println(string(body))
return nil
}
With semaphore like limiter
package main
import (
"context"
"fmt"
"io/ioutil"
"log"
"net/http"
"runtime"
"sync"
"golang.org/x/sync/semaphore"
)
const (
count = 200
limiter = 10
baseUrl = "https://jsonplaceholder.typicode.com/todos"
)
func main() {
wg := sync.WaitGroup{}
sem := semaphore.NewWeighted(int64(limiter))
wg.Add(count)
for i := 0; i < count; i++ {
if err := sem.Acquire(context.Background(), 1); err != nil {
log.Fatal(err)
}
go func(i int) {
defer wg.Done()
defer sem.Release(1)
getData(i)
}(i)
}
wg.Wait()
}
func getData(index int) error {
url := fmt.Sprintf("%s/%d", baseUrl, index)
res, err := http.Get(url)
if err != nil {
return err
}
defer res.Body.Close()
body, err := ioutil.ReadAll(res.Body)
if err != nil {
return err
}
fmt.Println(runtime.NumGoroutine())
fmt.Println(index)
fmt.Println(string(body))
return nil
}