xfy f12ffd180f chore: release v0.4.0
- Update CHANGELOG.md for v0.4.0
- Update Makefile FALLBACK_VERSION to 0.4.0
- Fix lint warnings (godoc comments, goconst)
- Clean up code formatting
2026-06-09 15:59:36 +08:00

67 lines
1.6 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

package loadbalance
import (
"sync/atomic"
"time"
)
// EWMAStats 使用原子操作实现的 EWMA指数加权移动平均统计器。
type EWMAStats struct {
headerTime atomic.Int64 // 首字节时间的 EWMA纳秒
lastByteTime atomic.Int64 // 完整响应时间的 EWMA纳秒
sampleCount atomic.Int64 // 样本计数
}
const defaultAlphaScale = 300 // alpha = 0.3
// NewEWMAStats 创建新的 EWMA 统计器。
func NewEWMAStats() *EWMAStats {
return &EWMAStats{}
}
// Record 记录一次响应时间样本。
func (e *EWMAStats) Record(headerTime, lastByteTime time.Duration) {
e.recordAtomic(&e.headerTime, headerTime)
e.recordAtomic(&e.lastByteTime, lastByteTime)
e.sampleCount.Add(1)
}
func (e *EWMAStats) recordAtomic(ptr *atomic.Int64, newValue time.Duration) {
newNano := newValue.Nanoseconds()
for {
old := ptr.Load()
if old == 0 {
if ptr.CompareAndSwap(0, newNano) {
return
}
continue
}
updated := (defaultAlphaScale*newNano + (1000-defaultAlphaScale)*old) / 1000
if ptr.CompareAndSwap(old, updated) {
return
}
}
}
// HeaderTime 返回首字节时间的 EWMA 值。
func (e *EWMAStats) HeaderTime() time.Duration {
return time.Duration(e.headerTime.Load())
}
// LastByteTime 返回完整响应时间的 EWMA 值。
func (e *EWMAStats) LastByteTime() time.Duration {
return time.Duration(e.lastByteTime.Load())
}
// SampleCount 返回已记录的样本数量。
func (e *EWMAStats) SampleCount() int64 {
return e.sampleCount.Load()
}
// Reset 重置所有统计数据。
func (e *EWMAStats) Reset() {
e.headerTime.Store(0)
e.lastByteTime.Store(0)
e.sampleCount.Store(0)
}