Initial commit
This commit is contained in:
@@ -0,0 +1,90 @@
|
||||
package api
|
||||
|
||||
import (
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"greq/internal/storage"
|
||||
)
|
||||
|
||||
// StressCount is the number of requests fired in a single stress run.
|
||||
const StressCount = 100
|
||||
|
||||
// StressConcurrency is the number of parallel workers.
|
||||
const StressConcurrency = 10
|
||||
|
||||
// StressResult holds the aggregated statistics of a load test.
|
||||
type StressResult struct {
|
||||
Total int
|
||||
Errors int
|
||||
MinDur time.Duration
|
||||
MaxDur time.Duration
|
||||
AvgDur time.Duration
|
||||
}
|
||||
|
||||
// ErrRate returns the error percentage (0–100).
|
||||
func (r StressResult) ErrRate() float64 {
|
||||
if r.Total == 0 {
|
||||
return 0
|
||||
}
|
||||
return float64(r.Errors) / float64(r.Total) * 100
|
||||
}
|
||||
|
||||
// RunStress fires StressCount HTTP requests against rf with StressConcurrency
|
||||
// parallel workers and returns aggregated timing statistics.
|
||||
func RunStress(rf storage.RequestFile, envs map[string]string) StressResult {
|
||||
type singleResult struct {
|
||||
dur time.Duration
|
||||
err bool
|
||||
}
|
||||
|
||||
results := make([]singleResult, StressCount)
|
||||
sem := make(chan struct{}, StressConcurrency)
|
||||
var mu sync.Mutex
|
||||
var wg sync.WaitGroup
|
||||
|
||||
for i := 0; i < StressCount; i++ {
|
||||
wg.Add(1)
|
||||
sem <- struct{}{}
|
||||
go func(idx int) {
|
||||
defer wg.Done()
|
||||
defer func() { <-sem }()
|
||||
|
||||
start := time.Now()
|
||||
_, err := Do(rf, envs)
|
||||
dur := time.Since(start)
|
||||
|
||||
mu.Lock()
|
||||
results[idx] = singleResult{dur: dur, err: err != nil}
|
||||
mu.Unlock()
|
||||
}(i)
|
||||
}
|
||||
|
||||
wg.Wait()
|
||||
|
||||
var errCount int
|
||||
var sumDur, minDur, maxDur time.Duration
|
||||
|
||||
for _, r := range results {
|
||||
if r.err {
|
||||
errCount++
|
||||
}
|
||||
sumDur += r.dur
|
||||
if minDur == 0 || r.dur < minDur {
|
||||
minDur = r.dur
|
||||
}
|
||||
if r.dur > maxDur {
|
||||
maxDur = r.dur
|
||||
}
|
||||
}
|
||||
|
||||
avgDur := time.Duration(int64(sumDur) / int64(StressCount))
|
||||
|
||||
return StressResult{
|
||||
Total: StressCount,
|
||||
Errors: errCount,
|
||||
MinDur: minDur,
|
||||
MaxDur: maxDur,
|
||||
AvgDur: avgDur,
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user