Skip to content

Commit

Permalink
Merge pull request #30 from robaho/master
Browse files Browse the repository at this point in the history
several improvements to your great app
  • Loading branch information
tsliwowicz authored Aug 18, 2024
2 parents 11e8328 + 601618e commit 095f3d7
Show file tree
Hide file tree
Showing 6 changed files with 169 additions and 44 deletions.
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
.DS_Store
.vscode/launch.json
go-wrk
31 changes: 20 additions & 11 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -41,21 +41,30 @@ Command line parameters (./go-wrk -help)
Basic Usage
-----------

./go-wrk -c 80 -d 5 http://192.168.1.118:8080/json
./go-wrk -c 2048 -d 10 http://localhost:8080/plaintext

This runs a benchmark for 5 seconds, using 80 go routines (connections)
This runs a benchmark for 10 seconds, using 2048 go routines (connections)

Output:

Running 10s test @ http://192.168.1.118:8080/json
80 goroutine(s) running concurrently
142470 requests in 4.949028953s, 19.57MB read
Requests/sec: 28787.47
Transfer/sec: 3.95MB
Avg Req Time: 0.0347ms
Fastest Request: 0.0340ms
Slowest Request: 0.0421ms
Number of Errors: 0
Running 10s test @ http://localhost:8080/plaintext
2048 goroutine(s) running concurrently
439977 requests in 10.012950719s, 52.45MB read
Requests/sec: 43940.79
Transfer/sec: 5.24MB
Fastest Request: 98µs
Avg Req Time: 46.608ms
Slowest Request: 398.431ms
Number of Errors: 0
Error Counts: map[]
10%: 164µs
50%: 2.382ms
75%: 3.83ms
99%: 5.403ms
99.9%: 5.488ms
99.9999%: 5.5ms
99.99999%: 5.5ms
stddev: 29.744ms


Benchmarking Tips
Expand Down
64 changes: 54 additions & 10 deletions go-wrk.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import (
"strings"
"time"

histo "github.com/HdrHistogram/hdrhistogram-go"
"github.com/tsliwowicz/go-wrk/loader"
"github.com/tsliwowicz/go-wrk/util"
)
Expand Down Expand Up @@ -38,6 +39,7 @@ var clientCert string
var clientKey string
var caCert string
var http2 bool
var cpus int = 0

func init() {
flag.BoolVar(&versionFlag, "v", false, "Print version details")
Expand All @@ -49,6 +51,7 @@ func init() {
flag.IntVar(&goroutines, "c", 10, "Number of goroutines to use (concurrent connections)")
flag.IntVar(&duration, "d", 10, "Duration of test in seconds")
flag.IntVar(&timeoutms, "T", 1000, "Socket/request timeout in ms")
flag.IntVar(&cpus, "cpus", 0, "Number of cpus, i.e. GOMAXPROCS. 0 = system default.")
flag.StringVar(&method, "M", "GET", "HTTP method")
flag.StringVar(&host, "host", "", "Host Header")
flag.Var(&headerFlags, "H", "Header to add to each request (you can define multiple -H flags)")
Expand All @@ -69,9 +72,15 @@ func printDefaults() {
})
}

func mapToString(m map[string]int) string {
s := make([]string,0,len(m))
for k,v := range m {
s = append(s,fmt.Sprint(k,"=",v))
}
return strings.Join(s,",")
}

func main() {
//raising the limits. Some performance gains were achieved with the + goroutines (not a lot).
runtime.GOMAXPROCS(runtime.NumCPU() + goroutines)

statsAggregator = make(chan *loader.RequesterStats, goroutines)
sigChan := make(chan os.Signal, 1)
Expand Down Expand Up @@ -112,6 +121,10 @@ func main() {
return
}

if cpus > 0 {
runtime.GOMAXPROCS(cpus)
}

fmt.Printf("Running %vs test @ %v\n %v goroutine(s) running concurrently\n", duration, testUrl, goroutines)

if len(reqBody) > 0 && reqBody[0] == '@' {
Expand All @@ -127,12 +140,14 @@ func main() {
loadGen := loader.NewLoadCfg(duration, goroutines, testUrl, reqBody, method, host, header, statsAggregator, timeoutms,
allowRedirectsFlag, disableCompression, disableKeepAlive, skipVerify, clientCert, clientKey, caCert, http2)

start := time.Now()

for i := 0; i < goroutines; i++ {
go loadGen.RunSingleLoadSession()
}

responders := 0
aggStats := loader.RequesterStats{MinRequestTime: time.Minute}
aggStats := loader.RequesterStats{ErrMap: make(map[string]int), Histogram: histo.New(1,int64(duration * 1000000),4)}

for responders < goroutines {
select {
Expand All @@ -144,25 +159,54 @@ func main() {
aggStats.NumRequests += stats.NumRequests
aggStats.TotRespSize += stats.TotRespSize
aggStats.TotDuration += stats.TotDuration
aggStats.MaxRequestTime = util.MaxDuration(aggStats.MaxRequestTime, stats.MaxRequestTime)
aggStats.MinRequestTime = util.MinDuration(aggStats.MinRequestTime, stats.MinRequestTime)
responders++
for k,v := range stats.ErrMap {
aggStats.ErrMap[k] += v
}
aggStats.Histogram.Merge(stats.Histogram)
}
}

duration := time.Now().Sub(start)

if aggStats.NumRequests == 0 {
fmt.Println("Error: No statistics collected / no requests found\n")
fmt.Println("Error: No statistics collected / no requests found")
fmt.Printf("Number of Errors:\t%v\n", aggStats.NumErrs)
if aggStats.NumErrs > 0 {
fmt.Printf("Error Counts:\t\t%v\n", mapToString(aggStats.ErrMap))
}
return
}

avgThreadDur := aggStats.TotDuration / time.Duration(responders) //need to average the aggregated duration

reqRate := float64(aggStats.NumRequests) / avgThreadDur.Seconds()
avgReqTime := aggStats.TotDuration / time.Duration(aggStats.NumRequests)
bytesRate := float64(aggStats.TotRespSize) / avgThreadDur.Seconds()

overallReqRate := float64(aggStats.NumRequests) / duration.Seconds()
overallBytesRate := float64(aggStats.TotRespSize) / duration.Seconds()

fmt.Printf("%v requests in %v, %v read\n", aggStats.NumRequests, avgThreadDur, util.ByteSize{float64(aggStats.TotRespSize)})
fmt.Printf("Requests/sec:\t\t%.2f\nTransfer/sec:\t\t%v\nAvg Req Time:\t\t%v\n", reqRate, util.ByteSize{bytesRate}, avgReqTime)
fmt.Printf("Fastest Request:\t%v\n", aggStats.MinRequestTime)
fmt.Printf("Slowest Request:\t%v\n", aggStats.MaxRequestTime)
fmt.Printf("Requests/sec:\t\t%.2f\nTransfer/sec:\t\t%v\n", reqRate, util.ByteSize{bytesRate})
fmt.Printf("Overall Requests/sec:\t%.2f\nOverall Transfer/sec:\t%v\n", overallReqRate, util.ByteSize{overallBytesRate})
fmt.Printf("Fastest Request:\t%v\n", toDuration(aggStats.Histogram.Min()))
fmt.Printf("Avg Req Time:\t\t%v\n", toDuration(int64(aggStats.Histogram.Mean())))
fmt.Printf("Slowest Request:\t%v\n", toDuration(aggStats.Histogram.Max()))
fmt.Printf("Number of Errors:\t%v\n", aggStats.NumErrs)
if aggStats.NumErrs > 0 {
fmt.Printf("Error Counts:\t\t%v\n", mapToString(aggStats.ErrMap))
}
fmt.Printf("10%%:\t\t\t%v\n", toDuration(aggStats.Histogram.ValueAtPercentile(.10)))
fmt.Printf("50%%:\t\t\t%v\n", toDuration(aggStats.Histogram.ValueAtPercentile(.50)))
fmt.Printf("75%%:\t\t\t%v\n", toDuration(aggStats.Histogram.ValueAtPercentile(.75)))
fmt.Printf("99%%:\t\t\t%v\n", toDuration(aggStats.Histogram.ValueAtPercentile(.99)))
fmt.Printf("99.9%%:\t\t\t%v\n", toDuration(aggStats.Histogram.ValueAtPercentile(.999)))
fmt.Printf("99.9999%%:\t\t%v\n", toDuration(aggStats.Histogram.ValueAtPercentile(.999999)))
fmt.Printf("99.99999%%:\t\t%v\n", toDuration(aggStats.Histogram.ValueAtPercentile(.9999999)))
fmt.Printf("stddev:\t\t\t%v\n", toDuration(int64(aggStats.Histogram.StdDev())))
// aggStats.Histogram.PercentilesPrint(os.Stdout,1,1)
}

func toDuration(usecs int64) time.Duration {
return time.Duration(usecs*1000)
}
5 changes: 4 additions & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,9 @@ module github.com/tsliwowicz/go-wrk

go 1.21

require golang.org/x/net v0.28.0
require (
github.com/HdrHistogram/hdrhistogram-go v1.1.2
golang.org/x/net v0.28.0
)

require golang.org/x/text v0.17.0 // indirect
60 changes: 60 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
@@ -1,4 +1,64 @@
dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU=
github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo=
github.com/HdrHistogram/hdrhistogram-go v1.1.2 h1:5IcZpTvzydCQeHzK4Ef/D5rrSqwxob0t8PQPMybUNFM=
github.com/HdrHistogram/hdrhistogram-go v1.1.2/go.mod h1:yDgFjdqOqDEKOvasDdhWNXYg9BVp4O+o5f6V/ehm6Oo=
github.com/ajstarks/svgo v0.0.0-20180226025133-644b8db467af/go.mod h1:K08gAheRH3/J6wwsYMMT4xOr94bZjxIelGM0+d/wbFw=
github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/fogleman/gg v1.2.1-0.20190220221249-0403632d5b90/go.mod h1:R/bRT+9gY/C5z7JzPU0zXsXHKM4/ayA+zqcVNZzPa1k=
github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU=
github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0/go.mod h1:E/TSTwGwJL78qG/PmXZO1EjYhfJinVAhrmmHX6Z8B9k=
github.com/google/go-cmp v0.5.4 h1:L8R9j+yAqZuZjsqh/z+F1NCffTKKLShY6zXTItVIZ8M=
github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/jung-kurt/gofpdf v1.0.3-0.20190309125859-24315acbbda5/go.mod h1:7Id9E/uU8ce6rXgefFLlgrJj/GYY22cpxn+r32jIOes=
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY=
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/exp v0.0.0-20180321215751-8460e604b9de/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
golang.org/x/exp v0.0.0-20180807140117-3d87b88a115f/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
golang.org/x/exp v0.0.0-20190125153040-c74c464bbbf2/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
golang.org/x/exp v0.0.0-20191030013958-a1ab85dbe136 h1:A1gGSx58LAGVHUUsOf7IiR0u8Xb6W51gRwfDBhkdcaw=
golang.org/x/exp v0.0.0-20191030013958-a1ab85dbe136/go.mod h1:JXzH8nQsPlswgeRAPE3MuO9GYsAcnJvJ4vnMwN/5qkY=
golang.org/x/image v0.0.0-20180708004352-c73c2afc3b81/go.mod h1:ux5Hcp/YLpHSI86hEcLt0YII63i6oz57MZXIpbrjZUs=
golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js=
golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=
golang.org/x/mobile v0.0.0-20190719004257-d2bd2a29d028/go.mod h1:E/iHnbuqvinMTCcRqshq8CkpyQDoeVncDDYHnLhea+o=
golang.org/x/mod v0.1.0/go.mod h1:0QHyrYULN0/3qlju5TqG8bIK38QM8yzMo5ekMj3DlcY=
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.28.0 h1:a9JDOJc5GMUJ0+UDqmLT86WiEy7iWyIhz8gz8E4e5hE=
golang.org/x/net v0.28.0/go.mod h1:yqtgsTWOOnlGLG9GFRrK3++bGOUEkNBoHZc8MEDWPNg=
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.17.0 h1:XtiM5bkSOt+ewxlOE/aE/AKEHibwj/6gvWMl9Rsh0Qc=
golang.org/x/text v0.17.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY=
golang.org/x/tools v0.0.0-20180525024113-a5b4c53f6e8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20190206041539-40960b6deb8e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20191012152004-8de300cfc20a/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
gonum.org/v1/gonum v0.0.0-20180816165407-929014505bf4/go.mod h1:Y+Yx5eoAFn32cQvJDxZx5Dpnq+c3wtXuadVZAcxbbBo=
gonum.org/v1/gonum v0.8.2 h1:CCXrcPKiGGotvnN6jfUsKk4rRqm7q09/YbKb5xCEvtM=
gonum.org/v1/gonum v0.8.2/go.mod h1:oe/vMfY3deqTw+1EZJhuvEW2iwGF1bW9wwu7XCu0+v0=
gonum.org/v1/netlib v0.0.0-20190313105609-8cb42192e0e0/go.mod h1:wa6Ws7BG/ESfp6dHfk7C6KdzKA7wR7u/rKwOGE66zvw=
gonum.org/v1/plot v0.0.0-20190515093506-e2840ee46a6b/go.mod h1:Wt8AAjI+ypCyYX3nZBvf6cAIx93T+c/OS2HFAYskSZc=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
rsc.io/pdf v0.1.1/go.mod h1:n8OzWcQ6Sp37PL01nO98y4iUCRdTGarVfzxY20ICaU4=
50 changes: 28 additions & 22 deletions loader/loader.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,16 +2,17 @@ package loader

import (
"bytes"
"errors"
"fmt"
"io"
"io/ioutil"
"log"
"net/http"
"net/url"
"strings"
"sync/atomic"
"time"

histo "github.com/HdrHistogram/hdrhistogram-go"
"github.com/tsliwowicz/go-wrk/util"
)

Expand Down Expand Up @@ -40,14 +41,14 @@ type LoadCfg struct {
http2 bool
}

// RequesterStats used for colelcting aggregate statistics
// RequesterStats used for collecting aggregate statistics
type RequesterStats struct {
TotRespSize int64
TotDuration time.Duration
MinRequestTime time.Duration
MaxRequestTime time.Duration
NumRequests int
NumErrs int
ErrMap map[string]int
Histogram *histo.Histogram
}

func NewLoadCfg(duration int, // seconds
Expand Down Expand Up @@ -103,7 +104,7 @@ func escapeUrlStr(in string) string {

// DoRequest single request implementation. Returns the size of the response and its duration
// On error - returns -1 on both
func DoRequest(httpClient *http.Client, header map[string]string, method, host, loadUrl, reqBody string) (respSize int, duration time.Duration) {
func DoRequest(httpClient *http.Client, header map[string]string, method, host, loadUrl, reqBody string) (respSize int, duration time.Duration, err error) {
respSize = -1
duration = -1

Expand All @@ -116,8 +117,7 @@ func DoRequest(httpClient *http.Client, header map[string]string, method, host,

req, err := http.NewRequest(method, loadUrl, buf)
if err != nil {
fmt.Println("An error occured doing request", err)
return
return 0,0,err
}

for hk, hv := range header {
Expand All @@ -131,28 +131,25 @@ func DoRequest(httpClient *http.Client, header map[string]string, method, host,
start := time.Now()
resp, err := httpClient.Do(req)
if err != nil {
fmt.Println("redirect?")
// this is a bit weird. When redirection is prevented, a url.Error is retuned. This creates an issue to distinguish
// between an invalid URL that was provided and and redirection error.
rr, ok := err.(*url.Error)
_, ok := err.(*url.Error)
if !ok {
fmt.Println("An error occured doing request", err, rr)
return
return 0,0,err
}
fmt.Println("An error occured doing request", err)
return 0,0,err
}
if resp == nil {
fmt.Println("empty response")
return
return 0,0,errors.New("empty response")
}
defer func() {
if resp != nil && resp.Body != nil {
resp.Body.Close()
}
}()
body, err := ioutil.ReadAll(resp.Body)
body, err := io.ReadAll(resp.Body)
if err != nil {
fmt.Println("An error occured reading body", err)
return 0,0,err
}
if resp.StatusCode/100 == 2 { // Treat all 2XX as successful
duration = time.Since(start)
Expand All @@ -161,16 +158,23 @@ func DoRequest(httpClient *http.Client, header map[string]string, method, host,
duration = time.Since(start)
respSize = int(resp.ContentLength) + int(util.EstimateHttpHeadersSize(resp.Header))
} else {
fmt.Println("received status code", resp.StatusCode, "from", resp.Header, "content", string(body), req)
return 0,0,errors.New(fmt.Sprint("received status code ", resp.StatusCode))
}

return
}

func unwrap(err error) error {
for errors.Unwrap(err)!=nil {
err = errors.Unwrap(err);
}
return err
}

// Requester a go function for repeatedly making requests and aggregating statistics as long as required
// When it is done, it sends the results using the statsAggregator channel
func (cfg *LoadCfg) RunSingleLoadSession() {
stats := &RequesterStats{MinRequestTime: time.Minute}
stats := &RequesterStats{ErrMap: make(map[string]int), Histogram: histo.New(1,int64(cfg.duration * 1000000),4)}
start := time.Now()

httpClient, err := client(cfg.disableCompression, cfg.disableKeepAlive, cfg.skipVerify,
Expand All @@ -180,12 +184,14 @@ func (cfg *LoadCfg) RunSingleLoadSession() {
}

for time.Since(start).Seconds() <= float64(cfg.duration) && atomic.LoadInt32(&cfg.interrupted) == 0 {
respSize, reqDur := DoRequest(httpClient, cfg.header, cfg.method, cfg.host, cfg.testUrl, cfg.reqBody)
if respSize > 0 {
respSize, reqDur, err := DoRequest(httpClient, cfg.header, cfg.method, cfg.host, cfg.testUrl, cfg.reqBody)
if err != nil {
stats.ErrMap[unwrap(err).Error()]+=1
stats.NumErrs++
} else if respSize > 0 {
stats.TotRespSize += int64(respSize)
stats.TotDuration += reqDur
stats.MaxRequestTime = util.MaxDuration(reqDur, stats.MaxRequestTime)
stats.MinRequestTime = util.MinDuration(reqDur, stats.MinRequestTime)
stats.Histogram.RecordValue(reqDur.Microseconds());
stats.NumRequests++
} else {
stats.NumErrs++
Expand Down

0 comments on commit 095f3d7

Please sign in to comment.