mirror of
https://github.com/aykhans/dodo.git
synced 2025-09-01 00:53:34 +00:00
🔨 Refactor 'Responses' type and its methods
This commit is contained in:
@@ -14,47 +14,30 @@ type Response struct {
|
|||||||
Time time.Duration
|
Time time.Duration
|
||||||
}
|
}
|
||||||
|
|
||||||
type Responses []*Response
|
type Responses []Response
|
||||||
|
|
||||||
// Print prints the responses in a tabular format, including information such as
|
// Print prints the responses in a tabular format, including information such as
|
||||||
// response count, minimum time, maximum time, average time, and latency percentiles.
|
// response count, minimum time, maximum time, average time, and latency percentiles.
|
||||||
func (responses Responses) Print() {
|
func (responses Responses) Print() {
|
||||||
total := struct {
|
if len(responses) == 0 {
|
||||||
Count int
|
return
|
||||||
Min time.Duration
|
|
||||||
Max time.Duration
|
|
||||||
Sum time.Duration
|
|
||||||
P90 time.Duration
|
|
||||||
P95 time.Duration
|
|
||||||
P99 time.Duration
|
|
||||||
}{
|
|
||||||
Count: len(responses),
|
|
||||||
Min: responses[0].Time,
|
|
||||||
Max: responses[0].Time,
|
|
||||||
}
|
}
|
||||||
mergedResponses := make(map[string]types.Durations)
|
|
||||||
var allDurations types.Durations
|
|
||||||
|
|
||||||
for _, response := range responses {
|
mergedResponses := make(map[string]types.Durations)
|
||||||
if response.Time < total.Min {
|
|
||||||
total.Min = response.Time
|
totalDurations := make(types.Durations, len(responses))
|
||||||
}
|
var totalSum time.Duration
|
||||||
if response.Time > total.Max {
|
totalCount := len(responses)
|
||||||
total.Max = response.Time
|
|
||||||
}
|
for i, response := range responses {
|
||||||
total.Sum += response.Time
|
totalSum += response.Time
|
||||||
|
totalDurations[i] = response.Time
|
||||||
|
|
||||||
mergedResponses[response.Response] = append(
|
mergedResponses[response.Response] = append(
|
||||||
mergedResponses[response.Response],
|
mergedResponses[response.Response],
|
||||||
response.Time,
|
response.Time,
|
||||||
)
|
)
|
||||||
allDurations = append(allDurations, response.Time)
|
|
||||||
}
|
}
|
||||||
allDurations.Sort()
|
|
||||||
allDurationsLenAsFloat := float64(len(allDurations) - 1)
|
|
||||||
total.P90 = allDurations[int(0.90*allDurationsLenAsFloat)]
|
|
||||||
total.P95 = allDurations[int(0.95*allDurationsLenAsFloat)]
|
|
||||||
total.P99 = allDurations[int(0.99*allDurationsLenAsFloat)]
|
|
||||||
|
|
||||||
t := table.NewWriter()
|
t := table.NewWriter()
|
||||||
t.SetOutputMirror(os.Stdout)
|
t.SetOutputMirror(os.Stdout)
|
||||||
@@ -93,15 +76,18 @@ func (responses Responses) Print() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if len(mergedResponses) > 1 {
|
if len(mergedResponses) > 1 {
|
||||||
|
totalDurations.Sort()
|
||||||
|
allDurationsLenAsFloat := float64(len(totalDurations) - 1)
|
||||||
|
|
||||||
t.AppendRow(table.Row{
|
t.AppendRow(table.Row{
|
||||||
"Total",
|
"Total",
|
||||||
total.Count,
|
totalCount,
|
||||||
utils.DurationRoundBy(total.Min, roundPrecision),
|
utils.DurationRoundBy(totalDurations[0], roundPrecision),
|
||||||
utils.DurationRoundBy(total.Max, roundPrecision),
|
utils.DurationRoundBy(totalDurations[len(totalDurations)-1], roundPrecision),
|
||||||
utils.DurationRoundBy(total.Sum/time.Duration(total.Count), roundPrecision), // Average
|
utils.DurationRoundBy(totalSum/time.Duration(totalCount), roundPrecision), // Average
|
||||||
utils.DurationRoundBy(total.P90, roundPrecision),
|
utils.DurationRoundBy(totalDurations[int(0.90*allDurationsLenAsFloat)], roundPrecision),
|
||||||
utils.DurationRoundBy(total.P95, roundPrecision),
|
utils.DurationRoundBy(totalDurations[int(0.95*allDurationsLenAsFloat)], roundPrecision),
|
||||||
utils.DurationRoundBy(total.P99, roundPrecision),
|
utils.DurationRoundBy(totalDurations[int(0.99*allDurationsLenAsFloat)], roundPrecision),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
t.Render()
|
t.Render()
|
||||||
|
@@ -66,7 +66,7 @@ func releaseDodos(
|
|||||||
streamWG sync.WaitGroup
|
streamWG sync.WaitGroup
|
||||||
requestCountPerDodo uint
|
requestCountPerDodo uint
|
||||||
dodosCount = requestConfig.GetValidDodosCountForRequests()
|
dodosCount = requestConfig.GetValidDodosCountForRequests()
|
||||||
responses = make([][]*Response, dodosCount)
|
responses = make([][]Response, dodosCount)
|
||||||
increase = make(chan int64, requestConfig.RequestCount)
|
increase = make(chan int64, requestConfig.RequestCount)
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -123,7 +123,7 @@ func sendRequestByCount(
|
|||||||
request *Request,
|
request *Request,
|
||||||
timeout time.Duration,
|
timeout time.Duration,
|
||||||
requestCount uint,
|
requestCount uint,
|
||||||
responseData *[]*Response,
|
responseData *[]Response,
|
||||||
increase chan<- int64,
|
increase chan<- int64,
|
||||||
wg *sync.WaitGroup,
|
wg *sync.WaitGroup,
|
||||||
) {
|
) {
|
||||||
@@ -146,7 +146,7 @@ func sendRequestByCount(
|
|||||||
if err == types.ErrInterrupt {
|
if err == types.ErrInterrupt {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
*responseData = append(*responseData, &Response{
|
*responseData = append(*responseData, Response{
|
||||||
Response: err.Error(),
|
Response: err.Error(),
|
||||||
Time: completedTime,
|
Time: completedTime,
|
||||||
})
|
})
|
||||||
@@ -154,7 +154,7 @@ func sendRequestByCount(
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
*responseData = append(*responseData, &Response{
|
*responseData = append(*responseData, Response{
|
||||||
Response: strconv.Itoa(response.StatusCode()),
|
Response: strconv.Itoa(response.StatusCode()),
|
||||||
Time: completedTime,
|
Time: completedTime,
|
||||||
})
|
})
|
||||||
@@ -170,7 +170,7 @@ func sendRequest(
|
|||||||
ctx context.Context,
|
ctx context.Context,
|
||||||
request *Request,
|
request *Request,
|
||||||
timeout time.Duration,
|
timeout time.Duration,
|
||||||
responseData *[]*Response,
|
responseData *[]Response,
|
||||||
increase chan<- int64,
|
increase chan<- int64,
|
||||||
wg *sync.WaitGroup,
|
wg *sync.WaitGroup,
|
||||||
) {
|
) {
|
||||||
@@ -193,7 +193,7 @@ func sendRequest(
|
|||||||
if err == types.ErrInterrupt {
|
if err == types.ErrInterrupt {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
*responseData = append(*responseData, &Response{
|
*responseData = append(*responseData, Response{
|
||||||
Response: err.Error(),
|
Response: err.Error(),
|
||||||
Time: completedTime,
|
Time: completedTime,
|
||||||
})
|
})
|
||||||
@@ -201,7 +201,7 @@ func sendRequest(
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
*responseData = append(*responseData, &Response{
|
*responseData = append(*responseData, Response{
|
||||||
Response: strconv.Itoa(response.StatusCode()),
|
Response: strconv.Itoa(response.StatusCode()),
|
||||||
Time: completedTime,
|
Time: completedTime,
|
||||||
})
|
})
|
||||||
|
@@ -1,6 +1,7 @@
|
|||||||
package types
|
package types
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"slices"
|
||||||
"sort"
|
"sort"
|
||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
@@ -14,9 +15,7 @@ func (d Durations) Sort(ascending ...bool) {
|
|||||||
return d[i] > d[j]
|
return d[i] > d[j]
|
||||||
})
|
})
|
||||||
} else { // Otherwise, sort in ascending order
|
} else { // Otherwise, sort in ascending order
|
||||||
sort.Slice(d, func(i, j int) bool {
|
slices.Sort(d)
|
||||||
return d[i] < d[j]
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -2,8 +2,8 @@ package utils
|
|||||||
|
|
||||||
import "math/rand"
|
import "math/rand"
|
||||||
|
|
||||||
func Flatten[T any](nested [][]*T) []*T {
|
func Flatten[T any](nested [][]T) []T {
|
||||||
flattened := make([]*T, 0)
|
flattened := make([]T, 0)
|
||||||
for _, n := range nested {
|
for _, n := range nested {
|
||||||
flattened = append(flattened, n...)
|
flattened = append(flattened, n...)
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user