-
Notifications
You must be signed in to change notification settings - Fork 0
/
aggregator.go
56 lines (50 loc) · 1.13 KB
/
aggregator.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
package gohammer
import (
"fmt"
"sort"
)
// runSummary represents summarized stats for a Run
type runSummary struct {
p99 int
p95 int
p90 int
p50 int
}
func aggregate(responses chan HammerResponse, stop chan bool) chan runSummary {
summary := make(chan runSummary)
go func() {
// Holds values in-memory
var latencies []int
for {
select {
// Continue reading from responses until signaled
// to stop by the channel.
case response := <-responses:
latencies = append(latencies, response.Latency)
outResponse(response)
// Signal to stop by the main routine,
// compute summary and report it back
case <-stop:
fmt.Println("Aggregator finished, summarizing")
summary <- summarize(latencies)
}
}
}()
return summary
}
func summarize(latencies []int) runSummary {
sort.Ints(latencies)
return runSummary{
p99: percentile(latencies, 99),
p95: percentile(latencies, 95),
p90: percentile(latencies, 90),
p50: percentile(latencies, 50),
}
}
func percentile(values []int, p float32) int {
if len(values) == 0 {
return 0
}
rank := int((p / 100) * float32(len(values)+1))
return values[rank-1]
}