Skip to content

Instantly share code, notes, and snippets.

@kenota
Created September 23, 2021 14:35
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save kenota/0ff2e5d8deb915a1a37508c937fefa9e to your computer and use it in GitHub Desktop.
Save kenota/0ff2e5d8deb915a1a37508c937fefa9e to your computer and use it in GitHub Desktop.
package main
import (
"flag"
"fmt"
"io"
"io/ioutil"
"log"
"net/http"
"sync"
"time"
)
type counter struct {
success int
failed int
rps int
mu sync.Mutex
}
func newCounter() *counter {
c := new(counter)
go func() {
for {
c.mu.Lock()
curr := c.success
c.mu.Unlock()
time.Sleep(time.Second)
c.mu.Lock()
c.rps = c.success - curr
c.mu.Unlock()
}
}()
return c
}
func (c *counter) Add() {
c.mu.Lock()
c.success++
c.mu.Unlock()
}
func (c *counter) AddFail() {
c.mu.Lock()
c.failed++
c.mu.Unlock()
}
func (c *counter) Report() (int, int, int) {
c.mu.Lock()
defer c.mu.Unlock()
return c.success, c.failed, c.rps
}
func main() {
var (
maxR = flag.Int("r", 100, "max goroutines to launch")
)
flag.Parse()
fmt.Printf("Launching %d goroutines \n", *maxR)
http.DefaultTransport.(*http.Transport).MaxIdleConnsPerHost = *maxR
client := &http.Client{Timeout: time.Millisecond * 200}
c := newCounter()
r, _ := http.NewRequest(http.MethodGet, "http://localhost:9090", nil)
r.Header.Add("X-Email-Id", "someone@example.com")
r.Header.Add("Connection", "keep-alive")
for i := 0; i < *maxR; i++ {
go func() {
for {
resp, err := client.Do(r)
if err != nil {
log.Printf("err sending req: %v", err)
c.AddFail()
continue
}
io.Copy(ioutil.Discard, resp.Body)
resp.Body.Close()
if resp.StatusCode == http.StatusOK {
c.Add()
} else {
c.AddFail()
log.Println("got resp code", resp.StatusCode)
}
}
}()
}
var s, f, rps int
for {
time.Sleep(time.Second * 10)
s, f, rps = c.Report()
log.Printf("\ntotal successful requests: %v\ntotal failed requests: %v\nrps: %v", s, f, rps)
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment