Skip to content

Commit 390778a

Browse files
deliahuMiguel Varela Ramos
authored and
Miguel Varela Ramos
committed
Improve dev/load.go script
1 parent 8addea0 commit 390778a

File tree

1 file changed

+103
-38
lines changed

1 file changed

+103
-38
lines changed

dev/load.go

Lines changed: 103 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -23,42 +23,46 @@ import (
2323
"io/ioutil"
2424
"net/http"
2525
"os"
26+
"os/signal"
2627
"strings"
2728
"sync"
29+
"syscall"
2830
"time"
2931

3032
"github.com/cortexlabs/cortex/pkg/lib/debug"
3133
"github.com/cortexlabs/cortex/pkg/lib/files"
34+
"go.uber.org/atomic"
3235
)
3336

3437
// usage: go run load.go <url> <sample.json OR sample json string>
3538

36-
// either set _numConcurrent > 0 or _requestInterval > 0 (and configure the corresponding sections)
37-
38-
// constant in-flight requests
39+
// configuration options (either set _numConcurrent > 0 or _requestInterval > 0, and configure the corresponding section)
3940
const (
41+
// constant in-flight requests
4042
_numConcurrent = 3
41-
_numRequestsPerThread = -1 // -1 means loop infinitely
42-
_requestDelay = 0 * time.Second
43-
_numMainLoops = 10 // only relevant if _numRequestsPerThread != -1
44-
)
43+
_requestDelay = 0 * time.Millisecond
44+
_numRequestsPerThread = 0 // 0 means loop infinitely
45+
_numMainLoops = 1 // only relevant if _numRequestsPerThread > 0
4546

46-
// constant requests per second
47-
const (
48-
_requestInterval = -1 * time.Millisecond
49-
_maxInFlight = 5
50-
)
47+
// constant requests per second
48+
_requestInterval = 0 * time.Millisecond
49+
_numRequests uint64 = 0 // 0 means loop infinitely
50+
_maxInFlight = 5
5151

52-
// other options
53-
const (
52+
// other options
5453
_printSuccessDots = true
54+
_printFailures = true
5555
)
5656

5757
type Counter struct {
5858
sync.Mutex
59-
count int
59+
count int64
6060
}
6161

62+
var _requestCount = atomic.Uint64{}
63+
var _successCount = atomic.Uint64{}
64+
var _failureCount = atomic.Uint64{}
65+
6266
var _client = &http.Client{
6367
Timeout: 0, // no timeout
6468
Transport: &http.Transport{
@@ -68,12 +72,12 @@ var _client = &http.Client{
6872

6973
func main() {
7074
if _numConcurrent > 0 && _requestInterval > 0 {
71-
fmt.Println("error: you must set either _numConcurrent or _requestInterval, but not both")
75+
fmt.Println("error: you must set either _numConcurrent or _requestInterval > 0, but not both")
7276
os.Exit(1)
7377
}
7478

7579
if _numConcurrent == 0 && _requestInterval == 0 {
76-
fmt.Println("error: you must set either _numConcurrent or _requestInterval")
80+
fmt.Println("error: you must set either _numConcurrent or _requestInterval > 0")
7781
os.Exit(1)
7882
}
7983

@@ -99,17 +103,31 @@ func runConstantRequestsPerSecond(url string, jsonBytes []byte) {
99103
ticker := time.NewTicker(_requestInterval)
100104
done := make(chan bool)
101105

106+
c := make(chan os.Signal)
107+
signal.Notify(c, os.Interrupt, syscall.SIGTERM)
108+
go func() {
109+
<-c
110+
done <- true
111+
}()
112+
113+
start := time.Now()
114+
115+
FOR_LOOP:
102116
for {
103117
select {
104118
case <-done:
105-
return
119+
break FOR_LOOP
106120
case <-ticker.C:
107-
go runConstantRequestsPerSecondIteration(url, jsonBytes, &inFlightCount)
121+
go runConstantRequestsPerSecondIteration(url, jsonBytes, &inFlightCount, done)
108122
}
109123
}
124+
125+
elapsed := time.Since(start)
126+
requestRate := float64(_requestCount.Load()) / elapsed.Seconds()
127+
fmt.Printf("\nelapsed time: %s | %d requests @ %f req/s | %d succeeded | %d failed\n", elapsed, _requestCount.Load(), requestRate, _successCount.Load(), _failureCount.Load())
110128
}
111129

112-
func runConstantRequestsPerSecondIteration(url string, jsonBytes []byte, inFlightCount *Counter) {
130+
func runConstantRequestsPerSecondIteration(url string, jsonBytes []byte, inFlightCount *Counter, done chan bool) {
113131
if _maxInFlight > 0 {
114132
inFlightCount.Lock()
115133
if inFlightCount.count >= _maxInFlight {
@@ -123,6 +141,10 @@ func runConstantRequestsPerSecondIteration(url string, jsonBytes []byte, inFligh
123141

124142
makeRequest(url, jsonBytes)
125143

144+
if _numRequests > 0 && _requestCount.Load() >= _numRequests {
145+
done <- true
146+
}
147+
126148
if _maxInFlight > 0 {
127149
inFlightCount.Lock()
128150
inFlightCount.count--
@@ -131,26 +153,52 @@ func runConstantRequestsPerSecondIteration(url string, jsonBytes []byte, inFligh
131153
}
132154

133155
func runConstantInFlight(url string, jsonBytes []byte) {
156+
if _numRequestsPerThread > 0 {
157+
fmt.Printf("spawning %d threads, %d requests each, %s delay on each\n", _numConcurrent, _numRequestsPerThread, _requestDelay.String())
158+
} else {
159+
fmt.Printf("spawning %d infinite threads, %s delay on each\n", _numConcurrent, _requestDelay.String())
160+
}
161+
162+
var summedRequestCount uint64
163+
var summedSuccessCount uint64
164+
var summedFailureCount uint64
165+
134166
start := time.Now()
135167
loopNum := 1
136168
for {
137-
runConstantInFlightIteration(url, jsonBytes)
138-
if loopNum >= _numMainLoops {
169+
wasKilled := runConstantInFlightIteration(url, jsonBytes, loopNum)
170+
171+
summedRequestCount += _requestCount.Load()
172+
summedSuccessCount += _successCount.Load()
173+
summedFailureCount += _failureCount.Load()
174+
_requestCount.Store(0)
175+
_successCount.Store(0)
176+
_failureCount.Store(0)
177+
178+
if loopNum >= _numMainLoops || wasKilled {
139179
break
140180
}
141181
loopNum++
142182
}
143-
fmt.Println("total elapsed time:", time.Since(start))
183+
184+
if _numMainLoops > 1 {
185+
elapsed := time.Since(start)
186+
requestRate := float64(summedRequestCount) / elapsed.Seconds()
187+
fmt.Printf("\ntotal elapsed time: %s | %d requests @ %f req/s | %d succeeded | %d failed\n", elapsed, summedRequestCount, requestRate, summedSuccessCount, summedFailureCount)
188+
}
144189
}
145190

146-
func runConstantInFlightIteration(url string, jsonBytes []byte) {
191+
func runConstantInFlightIteration(url string, jsonBytes []byte, loopNum int) bool {
147192
start := time.Now()
148193

149-
if _numRequestsPerThread > 0 {
150-
fmt.Printf("spawning %d threads, %d requests each, %s delay on each\n", _numConcurrent, _numRequestsPerThread, _requestDelay.String())
151-
} else {
152-
fmt.Printf("spawning %d infinite threads, %s delay on each\n", _numConcurrent, _requestDelay.String())
153-
}
194+
wasKilled := false
195+
killed := make(chan bool)
196+
c := make(chan os.Signal)
197+
signal.Notify(c, os.Interrupt, syscall.SIGTERM)
198+
go func() {
199+
<-c
200+
killed <- true
201+
}()
154202

155203
doneChans := make([]chan struct{}, _numConcurrent)
156204
for i := range doneChans {
@@ -166,12 +214,22 @@ func runConstantInFlightIteration(url string, jsonBytes []byte) {
166214
}()
167215
}
168216

217+
LOOP:
169218
for _, doneChan := range doneChans {
170-
<-doneChan
219+
select {
220+
case <-killed:
221+
wasKilled = true
222+
break LOOP
223+
case <-doneChan:
224+
continue
225+
}
171226
}
172227

173-
fmt.Println()
174-
fmt.Println("elapsed time:", time.Now().Sub(start))
228+
elapsed := time.Now().Sub(start)
229+
requestRate := float64(_requestCount.Load()) / elapsed.Seconds()
230+
fmt.Printf("\nelapsed time: %s | %d requests @ %f req/s | %d succeeded | %d failed\n", elapsed, _requestCount.Load(), requestRate, _successCount.Load(), _failureCount.Load())
231+
232+
return wasKilled
175233
}
176234

177235
func makeRequestLoop(url string, jsonBytes []byte) {
@@ -211,13 +269,20 @@ func makeRequest(url string, jsonBytes []byte) {
211269
body, bodyReadErr := ioutil.ReadAll(response.Body)
212270
response.Body.Close()
213271

214-
if response.StatusCode != 200 {
215-
if bodyReadErr == nil {
216-
fmt.Printf("\nstatus code: %d; body: %s\n", response.StatusCode, string(body))
217-
} else {
218-
fmt.Printf("\nstatus code: %d; error reading body: %s\n", response.StatusCode, bodyReadErr.Error())
272+
_requestCount.Inc()
273+
274+
if response.StatusCode == 200 {
275+
_successCount.Inc()
276+
} else {
277+
_failureCount.Inc()
278+
if _printFailures {
279+
if bodyReadErr == nil {
280+
fmt.Printf("\nstatus code: %d; body: %s\n", response.StatusCode, string(body))
281+
} else {
282+
fmt.Printf("\nstatus code: %d; error reading body: %s\n", response.StatusCode, bodyReadErr.Error())
283+
}
284+
return
219285
}
220-
return
221286
}
222287

223288
if _printSuccessDots {

0 commit comments

Comments
 (0)