From acecd827d6aad37b45aa9fd0310c811b29ad2b14 Mon Sep 17 00:00:00 2001 From: yusing Date: Sat, 27 Sep 2025 11:35:38 +0800 Subject: [PATCH] refactor(synk): consolidate pool statistics tracking and replace GC tracking with dropped tracking --- internal/utils/synk/pool.go | 27 +++++++++++--------- internal/utils/synk/pool_debug.go | 41 ++++++++++++++++--------------- internal/utils/synk/pool_prod.go | 9 +++---- 3 files changed, 41 insertions(+), 36 deletions(-) diff --git a/internal/utils/synk/pool.go b/internal/utils/synk/pool.go index 8774d9dd..83335443 100644 --- a/internal/utils/synk/pool.go +++ b/internal/utils/synk/pool.go @@ -101,6 +101,7 @@ func (p *BytesPool) Get() []byte { addReused(cap(bPtr)) return bPtr default: + addNonPooled(p.initSize) return make([]byte, 0, p.initSize) } } @@ -115,8 +116,7 @@ func (p *BytesPoolWithMemory) Get() []byte { if bPtr == nil { continue } - capB := cap(bPtr) - addReused(capB) + addReused(cap(bPtr)) return bPtr default: addNonPooled(size) @@ -129,25 +129,25 @@ func (p *BytesPool) GetSized(size int) []byte { for { select { case bWeak := <-p.sizedPool: - bPtr := getBufFromWeak(bWeak) - if bPtr == nil { + b := getBufFromWeak(bWeak) + if b == nil { continue } - capB := cap(bPtr) + capB := cap(b) remainingSize := capB - size if remainingSize == 0 { addReused(capB) - return bPtr[:size] + return b[:size] } if remainingSize > 0 { // capB > size (buffer larger than requested) addReused(size) - p.Put(bPtr[size:capB]) + p.Put(b[size:capB]) // return the first part and limit the capacity to the requested size - ret := bPtr[:size] + ret := b[:size] setLen(&ret, size) setCap(&ret, size) return ret @@ -157,6 +157,7 @@ func (p *BytesPool) GetSized(size int) []byte { select { case p.sizedPool <- bWeak: default: + addDropped(cap(b)) // just drop it } default: @@ -169,13 +170,14 @@ func (p *BytesPool) GetSized(size int) []byte { func (p *BytesPool) Put(b []byte) { size := cap(b) if size > DropThreshold { + addDropped(size) return } b = b[:0] if size >= SizedPoolThreshold { - p.put(makeWeak(&b), p.sizedPool) + p.put(size, makeWeak(&b), p.sizedPool) } else { - p.put(makeWeak(&b), p.unsizedPool) + p.put(size, makeWeak(&b), p.unsizedPool) } } @@ -208,6 +210,7 @@ func (p *BytesPoolWithMemory) Put(b []byte) { } if capB > DropThreshold { + addDropped(int(capB)) return } b = b[:0] @@ -215,15 +218,17 @@ func (p *BytesPoolWithMemory) Put(b []byte) { select { case p.pool <- w: default: + addDropped(int(capB)) // just drop it } } //go:inline -func (p *BytesPool) put(w weakBuf, pool chan weakBuf) { +func (p *BytesPool) put(size int, w weakBuf, pool chan weakBuf) { select { case pool <- w: default: + addDropped(size) // just drop it } } diff --git a/internal/utils/synk/pool_debug.go b/internal/utils/synk/pool_debug.go index 4d1a48b0..36584ccd 100644 --- a/internal/utils/synk/pool_debug.go +++ b/internal/utils/synk/pool_debug.go @@ -5,7 +5,6 @@ package synk import ( "os" "os/signal" - "runtime" "sync/atomic" "time" @@ -13,29 +12,31 @@ import ( "github.com/yusing/godoxy/internal/utils/strutils" ) +type poolCounters struct { + num atomic.Uint64 + size atomic.Uint64 +} + var ( - numNonPooled, sizeNonPooled uint64 - numReused, sizeReused uint64 - numGCed, sizeGCed uint64 + nonPooled poolCounters + dropped poolCounters + reused poolCounters ) func addNonPooled(size int) { - atomic.AddUint64(&numNonPooled, 1) - atomic.AddUint64(&sizeNonPooled, uint64(size)) + nonPooled.num.Add(1) + nonPooled.size.Add(uint64(size)) } func addReused(size int) { - atomic.AddUint64(&numReused, 1) - atomic.AddUint64(&sizeReused, uint64(size)) + reused.num.Add(1) + reused.size.Add(uint64(size)) } - -func addGCed(size int) { - atomic.AddUint64(&numGCed, 1) - atomic.AddUint64(&sizeGCed, uint64(size)) +func addDropped(size int) { + dropped.num.Add(1) + dropped.size.Add(uint64(size)) } -var addCleanup = runtime.AddCleanup[[]byte, int] - func initPoolStats() { go func() { statsTicker := time.NewTicker(5 * time.Second) @@ -50,12 +51,12 @@ func initPoolStats() { return case <-statsTicker.C: log.Info(). - Uint64("numReused", atomic.LoadUint64(&numReused)). - Str("sizeReused", strutils.FormatByteSize(atomic.LoadUint64(&sizeReused))). - Uint64("numGCed", atomic.LoadUint64(&numGCed)). - Str("sizeGCed", strutils.FormatByteSize(atomic.LoadUint64(&sizeGCed))). - Uint64("numNonPooled", atomic.LoadUint64(&numNonPooled)). - Str("sizeNonPooled", strutils.FormatByteSize(atomic.LoadUint64(&sizeNonPooled))). + Uint64("numReused", reused.num.Load()). + Str("sizeReused", strutils.FormatByteSize(reused.size.Load())). + Uint64("numDropped", dropped.num.Load()). + Str("sizeDropped", strutils.FormatByteSize(dropped.size.Load())). + Uint64("numNonPooled", nonPooled.num.Load()). + Str("sizeNonPooled", strutils.FormatByteSize(nonPooled.size.Load())). Msg("bytes pool stats") } } diff --git a/internal/utils/synk/pool_prod.go b/internal/utils/synk/pool_prod.go index b1708aa1..88bc0aa6 100644 --- a/internal/utils/synk/pool_prod.go +++ b/internal/utils/synk/pool_prod.go @@ -2,8 +2,7 @@ package synk -func addNonPooled(size int) {} -func addReused(size int) {} -func addGCed(size int) {} -func initPoolStats() {} -func addCleanup(ptr *[]byte, cleanup func(int), arg int) {} +func addNonPooled(size int) {} +func addDropped(size int) {} +func addReused(size int) {} +func initPoolStats() {}