I am new to Go and am looking for the correct way of using net/http or fasthttp with goroutines. Unfortunately there are not many fasthttp client examples out there.
I found the following code: (Example1)
package main
import (
"bufio"
"fmt"
"github.com/valyala/fasthttp"
"log"
"net"
"os"
"sync"
"time"
)
func grabPage(fastClient *fasthttp.Client, i int, wg *sync.WaitGroup) {
defer wg.Done()
_, body, err := fastClient.GetTimeout(nil, "https://en.wikipedia.org/wiki/Immanuel_Kant", time.Duration(time.Second*20))
if err != nil {
log.Fatal(err)
}
f, err := os.Create(fmt.Sprintf("./data/%d.txt", i))
if err != nil {
log.Fatal(err)
}
defer f.Close()
w := bufio.NewWriter(f)
w.Write(body)
}
func main() {
var wg sync.WaitGroup
total := 500
c := &fasthttp.Client{
Dial: func(addr string) (net.Conn, error) {
return fasthttp.DialTimeout(addr, time.Second*10)
},
MaxConnsPerHost: total,
}
wg.Add(total)
for index := 0; index < total; index++ {
go grabPage(c, index, &wg)
}
wg.Wait()
}
In this code the developer creates a fasthttp.Client instance in the main() function and passes it to the goroutine using go grabPage(c, ...). For my understanding, this way you create one instance and all the requests use this one instance to do the job.
On another page, a developer uses something like that: (Example2)
func grabPage(i int, wg *sync.WaitGroup) {
defer wg.Done()
fastClient := &fasthttp.Client{
Dial: func(addr string) (net.Conn, error) {
return fasthttp.DialTimeout(addr, time.Second*10)
},
MaxConnsPerHost: 500,
}
_, body, err := fastClient.GetTimeout(nil, "https://en.wikipedia.org/wiki/Immanuel_Kant", time.Duration(time.Second*20))
if err != nil {
log.Fatal(err)
}
f, err := os.Create(fmt.Sprintf("./data/%d.txt", i))
if err != nil {
log.Fatal(err)
}
defer f.Close()
w := bufio.NewWriter(f)
w.Write(body)
}
The big question is, are both solutions correct? Or does the Example2 solution really create a new instance and use a lot of memory for every goroutine?
I made the examples out of snippets for my question, in the Example2 for sure defer are missing. This is not part of the question.
A small side question:
(fastClient *fasthttp.Client, i int, wg *sync.WaitGroup) -> fastClient and wg are pointers, so why call grabPage(c, index, &wg) and not grabPage(&c, index, &wg)?