package main import ( "sort" "sync" "time" ) // latency collects request durations and reports percentiles. It is safe for // concurrent recording. type latency struct { mu sync.Mutex samples []time.Duration } func (l *latency) record(d time.Duration) { l.mu.Lock() l.samples = append(l.samples, d) l.mu.Unlock() } func (l *latency) count() int { l.mu.Lock() defer l.mu.Unlock() return len(l.samples) } // percentiles returns p50/p90/p99 and the max. Returns zeros when empty. func (l *latency) percentiles() (p50, p90, p99, max time.Duration) { l.mu.Lock() s := append([]time.Duration(nil), l.samples...) l.mu.Unlock() if len(s) == 0 { return 0, 0, 0, 0 } sort.Slice(s, func(i, j int) bool { return s[i] < s[j] }) at := func(q float64) time.Duration { idx := int(q * float64(len(s)-1)) return s[idx] } return at(0.50), at(0.90), at(0.99), s[len(s)-1] }