Skip to content

Instantly share code, notes, and snippets.

@dmfed
Last active September 22, 2021 20:55
Show Gist options
  • Save dmfed/dbc9f08df51ef8dd19c1dee94235aec6 to your computer and use it in GitHub Desktop.
Save dmfed/dbc9f08df51ef8dd19c1dee94235aec6 to your computer and use it in GitHub Desktop.
package main
import (
"flag"
"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()
defer c.mu.Unlock()
c.success++
}
func (c *counter) AddFail() {
c.mu.Lock()
defer c.mu.Unlock()
c.failed++
}
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()
client := &http.Client{Timeout: time.Minute * 2}
c := newCounter()
r, _ := http.NewRequest(http.MethodGet, "http://somehost.tech", nil)
r.Header.Add("X-Email-Id", "[email protected]")
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