fix: harden single-machine load handling

This commit is contained in:
richjohnrambo
2026-09-29 17:52:13 +08:00
parent ab73b69870
commit 4b00b5ae37
24 changed files with 1030 additions and 144 deletions
+18 -20
View File
@@ -2,7 +2,7 @@ package main
import (
"sort"
"sync"
"sync/atomic"
"time"
)
@@ -13,11 +13,10 @@ var latencyBounds = []time.Duration{
}
type DurationHistogram struct {
mu sync.Mutex
count int64
sum time.Duration
max time.Duration
bucket []int64
count atomic.Int64
sum atomic.Int64
max atomic.Int64
bucket []atomic.Int64
}
type HistogramSnapshot struct {
@@ -28,37 +27,36 @@ type HistogramSnapshot struct {
}
func NewDurationHistogram() *DurationHistogram {
return &DurationHistogram{bucket: make([]int64, len(latencyBounds)+1)}
return &DurationHistogram{bucket: make([]atomic.Int64, len(latencyBounds)+1)}
}
func (h *DurationHistogram) Observe(value time.Duration) {
if value < 0 {
return
}
h.mu.Lock()
defer h.mu.Unlock()
h.count++
h.sum += value
if value > h.max {
h.max = value
nanos := int64(value)
h.count.Add(1)
h.sum.Add(nanos)
for previous := h.max.Load(); nanos > previous; previous = h.max.Load() {
if h.max.CompareAndSwap(previous, nanos) {
break
}
}
idx := sort.Search(len(latencyBounds), func(i int) bool { return value <= latencyBounds[i] })
h.bucket[idx]++
h.bucket[idx].Add(1)
}
func (h *DurationHistogram) Snapshot() HistogramSnapshot {
h.mu.Lock()
defer h.mu.Unlock()
buckets := make(map[string]int64, len(h.bucket))
for i, count := range h.bucket {
for i := range h.bucket {
label := "+Inf"
if i < len(latencyBounds) {
label = latencyBounds[i].String()
}
buckets[label] = count
buckets[label] = h.bucket[i].Load()
}
return HistogramSnapshot{
Count: h.count, SumMS: float64(h.sum) / float64(time.Millisecond),
MaxMS: float64(h.max) / float64(time.Millisecond), Buckets: buckets,
Count: h.count.Load(), SumMS: float64(h.sum.Load()) / float64(time.Millisecond),
MaxMS: float64(h.max.Load()) / float64(time.Millisecond), Buckets: buckets,
}
}