From 91106f0c34e1b1a1836bf9cd460ccfa97ece2122 Mon Sep 17 00:00:00 2001 From: sashayakovtseva Date: Wed, 29 Nov 2023 13:32:41 +0300 Subject: [PATCH 1/7] Add a separate metrics structure Signed-off-by: sashayakovtseva --- go.mod | 13 +++++++- go.sum | 39 ++++++++++++++++++++++-- metrics.go | 87 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 135 insertions(+), 4 deletions(-) create mode 100644 metrics.go diff --git a/go.mod b/go.mod index b66cc9c..d943d0e 100644 --- a/go.mod +++ b/go.mod @@ -3,12 +3,23 @@ module github.com/jackc/puddle/v2 go 1.19 require ( + github.com/prometheus/client_golang v1.17.0 github.com/stretchr/testify v1.8.1 - golang.org/x/sync v0.1.0 + golang.org/x/sync v0.3.0 ) require ( + github.com/beorn7/perks v1.0.1 // indirect + github.com/cespare/xxhash/v2 v2.2.0 // indirect github.com/davecgh/go-spew v1.1.1 // indirect + github.com/golang/protobuf v1.5.3 // indirect + github.com/kr/text v0.2.0 // indirect + github.com/matttproud/golang_protobuf_extensions v1.0.4 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect + github.com/prometheus/client_model v0.4.1-0.20230718164431-9a2bf3000d16 // indirect + github.com/prometheus/common v0.44.0 // indirect + github.com/prometheus/procfs v0.11.1 // indirect + golang.org/x/sys v0.11.0 // indirect + google.golang.org/protobuf v1.31.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect ) diff --git a/go.sum b/go.sum index 96e82f8..603b09d 100644 --- a/go.sum +++ b/go.sum @@ -1,8 +1,33 @@ +github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= +github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw= +github.com/cespare/xxhash/v2 v2.2.0 h1:DC2CZ1Ep5Y4k3ZQ899DldepgrayRUGE6BBZ/cd9Cj44= +github.com/cespare/xxhash/v2 v2.2.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= +github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= +github.com/golang/protobuf v1.5.3 h1:KhyjKVUg7Usr/dYsdSqoFveMYd5ko72D+zANwlG1mmg= +github.com/golang/protobuf v1.5.3/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= +github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38= +github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= +github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= +github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= +github.com/matttproud/golang_protobuf_extensions v1.0.4 h1:mmDVorXM7PCGKw94cs5zkfA9PSy5pEvNWRP0ET0TIVo= +github.com/matttproud/golang_protobuf_extensions v1.0.4/go.mod h1:BSXmuO+STAnVfrANrmjBb36TMTDstsz7MSK+HVaYKv4= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/prometheus/client_golang v1.17.0 h1:rl2sfwZMtSthVU752MqfjQozy7blglC+1SOtjMAMh+Q= +github.com/prometheus/client_golang v1.17.0/go.mod h1:VeL+gMmOAxkS2IqfCq0ZmHSL+LjWfWDUmp1mBz9JgUY= +github.com/prometheus/client_model v0.4.1-0.20230718164431-9a2bf3000d16 h1:v7DLqVdK4VrYkVD5diGdl4sxJurKJEMnODWRJlxV9oM= +github.com/prometheus/client_model v0.4.1-0.20230718164431-9a2bf3000d16/go.mod h1:oMQmHW1/JoDwqLtg57MGgP/Fb1CJEYF2imWWhWtMkYU= +github.com/prometheus/common v0.44.0 h1:+5BrQJwiBB9xsMygAB3TNvpQKOwlkc25LbISbrdOOfY= +github.com/prometheus/common v0.44.0/go.mod h1:ofAIvZbQ1e/nugmZGz4/qCb9Ap1VoSTIO7x0VV9VvuY= +github.com/prometheus/procfs v0.11.1 h1:xRC8Iq1yyca5ypa9n1EZnWZkt7dwcoRPQwX/5gwaUuI= +github.com/prometheus/procfs v0.11.1/go.mod h1:eesXgaPo1q7lBpVMoMy0ZOFTth9hBn4W/y0/p/ScXhY= +github.com/rogpeppe/go-internal v1.10.0 h1:TMyTOH3F/DB16zRVcYyreMH6GnZZrwQVAoYjRBZyWFQ= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= @@ -10,10 +35,18 @@ github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/ github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= github.com/stretchr/testify v1.8.1 h1:w7B6lhMri9wdJUVmEZPGGhZzrYTPvgJArz7wNPgYKsk= github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= -golang.org/x/sync v0.1.0 h1:wsuoTGHzEhffawBOhz5CYhcrV4IdKZbEyZjBMuTp12o= -golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM= +golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.3.0 h1:ftCYgMx6zT/asHUrPw8BLLscYtGznsLAnjq5RH9P66E= +golang.org/x/sync v0.3.0/go.mod h1:FU7BRWz2tNW+3quACPkgCx/L+uEAv1htQ0V83Z9Rj+Y= +golang.org/x/sys v0.11.0 h1:eG7RXZHdqOJ1i+0lgLgCpSXAp6M3LYlAo6osgSi0xOM= +golang.org/x/sys v0.11.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= +google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= +google.golang.org/protobuf v1.31.0 h1:g0LDEJHgrBl9N9r17Ru3sqWhkIx2NB67okBHPwC7hs8= +google.golang.org/protobuf v1.31.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= diff --git a/metrics.go b/metrics.go new file mode 100644 index 0000000..1965c40 --- /dev/null +++ b/metrics.go @@ -0,0 +1,87 @@ +package puddle + +import ( + "strconv" + "sync/atomic" + "time" + + "github.com/prometheus/client_golang/prometheus" +) + +// Metrics hold puddle metrics. +type Metrics struct { + acquireCount int64 + acquireDuration time.Duration + emptyAcquireCount int64 + canceledAcquireCount atomic.Int64 + // acquireDurationHistogram can be nil + acquireDurationHistogram *prometheus.HistogramVec +} + +func NewMetrics(opts ...MetricsOption) *Metrics { + var m Metrics + for _, o := range opts { + o(&m) + } + return &m +} + +func (m *Metrics) observeAcquireDuration(d time.Duration, isEmptyAcquire bool) { + m.acquireCount++ + m.acquireDuration += d + if isEmptyAcquire { + m.emptyAcquireCount++ + } + + if m.acquireDurationHistogram != nil { + m.acquireDurationHistogram. + WithLabelValues(strconv.FormatBool(isEmptyAcquire)). + Observe(float64(d.Nanoseconds())) + } +} + +func (m *Metrics) observeAcquireCancel() { + m.canceledAcquireCount.Add(1) +} + +type MetricsOption func(m *Metrics) + +// WithAcquireDurationHistogram turns on recording of pool resource acquire duration. +// Histogram metrics can be very expensive for Prometheus to retain and query. +func WithAcquireDurationHistogram(reg prometheus.Registerer, opts ...HistogramOption) MetricsOption { + return func(m *Metrics) { + histOpts := prometheus.HistogramOpts{ + Name: "puddle_acquire_duration_nanoseconds", + Help: "Histogram of a pool resource acquire duration (nanoseconds).", + Buckets: prometheus.DefBuckets, + } + for _, o := range opts { + o(&histOpts) + } + + m.acquireDurationHistogram = prometheus.NewHistogramVec(histOpts, []string{"empty"}) + reg.MustRegister(m.acquireDurationHistogram) + } +} + +// A HistogramOption lets you add options to Histogram metrics using With* funcs. +type HistogramOption func(*prometheus.HistogramOpts) + +// WithHistogramBuckets allows you to specify custom bucket ranges for histograms. +func WithHistogramBuckets(buckets []float64) HistogramOption { + return func(o *prometheus.HistogramOpts) { o.Buckets = buckets } +} + +// WithHistogramConstLabels allows you to add custom ConstLabels to histograms metrics. +func WithHistogramConstLabels(labels prometheus.Labels) HistogramOption { + return func(o *prometheus.HistogramOpts) { + o.ConstLabels = labels + } +} + +// WithHistogramSubsystem allows you to add a Subsystem to histograms metrics. +func WithHistogramSubsystem(subsystem string) HistogramOption { + return func(o *prometheus.HistogramOpts) { + o.Subsystem = subsystem + } +} From 813621014f862fb5490c7c7c03d7bade5963b6bd Mon Sep 17 00:00:00 2001 From: sashayakovtseva Date: Wed, 29 Nov 2023 13:42:43 +0300 Subject: [PATCH 2/7] Use metrics instead of built-in counters Signed-off-by: sashayakovtseva --- pool.go | 65 ++++++++++++++++++++++++++++----------------------------- 1 file changed, 32 insertions(+), 33 deletions(-) diff --git a/pool.go b/pool.go index c8edc0f..a9bcd41 100644 --- a/pool.go +++ b/pool.go @@ -4,11 +4,11 @@ import ( "context" "errors" "sync" - "sync/atomic" "time" - "github.com/jackc/puddle/v2/internal/genstack" "golang.org/x/sync/semaphore" + + "github.com/jackc/puddle/v2/internal/genstack" ) const ( @@ -132,15 +132,12 @@ type Pool[T any] struct { allResources resList[T] idleResources *genstack.GenStack[*Resource[T]] + metrics *Metrics + constructor Constructor[T] destructor Destructor[T] maxSize int32 - acquireCount int64 - acquireDuration time.Duration - emptyAcquireCount int64 - canceledAcquireCount atomic.Int64 - resetCount int baseAcquireCtx context.Context @@ -149,6 +146,7 @@ type Pool[T any] struct { } type Config[T any] struct { + Metrics *Metrics Constructor Constructor[T] Destructor Destructor[T] MaxSize int32 @@ -160,17 +158,22 @@ func NewPool[T any](config *Config[T]) (*Pool[T], error) { return nil, errors.New("MaxSize must be >= 1") } - baseAcquireCtx, cancelBaseAcquireCtx := context.WithCancel(context.Background()) + p := &Pool[T]{ + acquireSem: semaphore.NewWeighted(int64(config.MaxSize)), + idleResources: genstack.NewGenStack[*Resource[T]](), + maxSize: config.MaxSize, + constructor: config.Constructor, + destructor: config.Destructor, + metrics: config.Metrics, + } + + p.baseAcquireCtx, p.cancelBaseAcquireCtx = context.WithCancel(context.Background()) - return &Pool[T]{ - acquireSem: semaphore.NewWeighted(int64(config.MaxSize)), - idleResources: genstack.NewGenStack[*Resource[T]](), - maxSize: config.MaxSize, - constructor: config.Constructor, - destructor: config.Destructor, - baseAcquireCtx: baseAcquireCtx, - cancelBaseAcquireCtx: cancelBaseAcquireCtx, - }, nil + if p.metrics == nil { + p.metrics = NewMetrics() + } + + return p, nil } // Close destroys all resources in the pool and rejects future Acquire calls. @@ -264,10 +267,10 @@ func (p *Pool[T]) Stat() *Stat { s := &Stat{ maxResources: p.maxSize, - acquireCount: p.acquireCount, - emptyAcquireCount: p.emptyAcquireCount, - canceledAcquireCount: p.canceledAcquireCount.Load(), - acquireDuration: p.acquireDuration, + acquireCount: p.metrics.acquireCount, + emptyAcquireCount: p.metrics.emptyAcquireCount, + canceledAcquireCount: p.metrics.canceledAcquireCount.Load(), + acquireDuration: p.metrics.acquireDuration, } for _, res := range p.allResources { @@ -329,7 +332,7 @@ func (p *Pool[T]) createNewResource() *Resource[T] { func (p *Pool[T]) Acquire(ctx context.Context) (_ *Resource[T], err error) { select { case <-ctx.Done(): - p.canceledAcquireCount.Add(1) + p.metrics.observeAcquireCancel() return nil, ctx.Err() default: } @@ -349,7 +352,7 @@ func (p *Pool[T]) acquire(ctx context.Context) (*Resource[T], error) { waitedForLock = true err := p.acquireSem.Acquire(ctx, 1) if err != nil { - p.canceledAcquireCount.Add(1) + p.metrics.observeAcquireCancel() return nil, err } } @@ -363,11 +366,8 @@ func (p *Pool[T]) acquire(ctx context.Context) (*Resource[T], error) { // If a resource is available in the pool. if res := p.tryAcquireIdleResource(); res != nil { - if waitedForLock { - p.emptyAcquireCount += 1 - } - p.acquireCount += 1 - p.acquireDuration += time.Duration(nanotime() - startNano) + d := time.Duration(nanotime() - startNano) + p.metrics.observeAcquireDuration(d, waitedForLock) p.mux.Unlock() return res, nil } @@ -389,9 +389,8 @@ func (p *Pool[T]) acquire(ctx context.Context) (*Resource[T], error) { p.mux.Lock() defer p.mux.Unlock() - p.emptyAcquireCount += 1 - p.acquireCount += 1 - p.acquireDuration += time.Duration(nanotime() - startNano) + d := time.Duration(nanotime() - startNano) + p.metrics.observeAcquireDuration(d, true) return res, nil } @@ -444,7 +443,7 @@ func (p *Pool[T]) initResourceValue(ctx context.Context, res *Resource[T]) (*Res select { case <-ctx.Done(): - p.canceledAcquireCount.Add(1) + p.metrics.observeAcquireCancel() return nil, ctx.Err() case err := <-constructErrChan: if err != nil { @@ -472,7 +471,7 @@ func (p *Pool[T]) TryAcquire(ctx context.Context) (*Resource[T], error) { // If a resource is available now if res := p.tryAcquireIdleResource(); res != nil { - p.acquireCount += 1 + p.metrics.observeAcquireDuration(0, false) return res, nil } From 4d98c2f1e727377897d68421c6540a57e91a1cf5 Mon Sep 17 00:00:00 2001 From: sashayakovtseva Date: Wed, 29 Nov 2023 13:52:38 +0300 Subject: [PATCH 3/7] Update dependencies version Signed-off-by: sashayakovtseva --- go.mod | 4 ++-- go.sum | 15 ++++----------- 2 files changed, 6 insertions(+), 13 deletions(-) diff --git a/go.mod b/go.mod index d943d0e..6c72ec9 100644 --- a/go.mod +++ b/go.mod @@ -4,8 +4,8 @@ go 1.19 require ( github.com/prometheus/client_golang v1.17.0 - github.com/stretchr/testify v1.8.1 - golang.org/x/sync v0.3.0 + github.com/stretchr/testify v1.8.4 + golang.org/x/sync v0.5.0 ) require ( diff --git a/go.sum b/go.sum index 603b09d..62e7ec6 100644 --- a/go.sum +++ b/go.sum @@ -3,7 +3,6 @@ github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6r github.com/cespare/xxhash/v2 v2.2.0 h1:DC2CZ1Ep5Y4k3ZQ899DldepgrayRUGE6BBZ/cd9Cj44= github.com/cespare/xxhash/v2 v2.2.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= -github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= @@ -28,16 +27,11 @@ github.com/prometheus/common v0.44.0/go.mod h1:ofAIvZbQ1e/nugmZGz4/qCb9Ap1VoSTIO github.com/prometheus/procfs v0.11.1 h1:xRC8Iq1yyca5ypa9n1EZnWZkt7dwcoRPQwX/5gwaUuI= github.com/prometheus/procfs v0.11.1/go.mod h1:eesXgaPo1q7lBpVMoMy0ZOFTth9hBn4W/y0/p/ScXhY= github.com/rogpeppe/go-internal v1.10.0 h1:TMyTOH3F/DB16zRVcYyreMH6GnZZrwQVAoYjRBZyWFQ= -github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= -github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= -github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= -github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= -github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= -github.com/stretchr/testify v1.8.1 h1:w7B6lhMri9wdJUVmEZPGGhZzrYTPvgJArz7wNPgYKsk= -github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= +github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk= +github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.3.0 h1:ftCYgMx6zT/asHUrPw8BLLscYtGznsLAnjq5RH9P66E= -golang.org/x/sync v0.3.0/go.mod h1:FU7BRWz2tNW+3quACPkgCx/L+uEAv1htQ0V83Z9Rj+Y= +golang.org/x/sync v0.5.0 h1:60k92dhOjHxJkrqnwsfl8KuaHbn/5dl0lUPUklKo3qE= +golang.org/x/sync v0.5.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sys v0.11.0 h1:eG7RXZHdqOJ1i+0lgLgCpSXAp6M3LYlAo6osgSi0xOM= golang.org/x/sys v0.11.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= @@ -47,6 +41,5 @@ google.golang.org/protobuf v1.31.0 h1:g0LDEJHgrBl9N9r17Ru3sqWhkIx2NB67okBHPwC7hs google.golang.org/protobuf v1.31.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= -gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= From e3458aa5f4164bf0d5ecac87cbbe9d786d6ef317 Mon Sep 17 00:00:00 2001 From: sashayakovtseva Date: Mon, 4 Dec 2023 15:38:06 +0300 Subject: [PATCH 4/7] Use callback instead of prom dependency Signed-off-by: sashayakovtseva --- go.mod | 14 +++-------- go.sum | 36 +++++++---------------------- metrics.go | 68 ++++++++++++++---------------------------------------- 3 files changed, 28 insertions(+), 90 deletions(-) diff --git a/go.mod b/go.mod index 6c72ec9..bd15a7c 100644 --- a/go.mod +++ b/go.mod @@ -3,23 +3,15 @@ module github.com/jackc/puddle/v2 go 1.19 require ( - github.com/prometheus/client_golang v1.17.0 github.com/stretchr/testify v1.8.4 golang.org/x/sync v0.5.0 ) require ( - github.com/beorn7/perks v1.0.1 // indirect - github.com/cespare/xxhash/v2 v2.2.0 // indirect github.com/davecgh/go-spew v1.1.1 // indirect - github.com/golang/protobuf v1.5.3 // indirect - github.com/kr/text v0.2.0 // indirect - github.com/matttproud/golang_protobuf_extensions v1.0.4 // indirect + github.com/kr/pretty v0.3.1 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect - github.com/prometheus/client_model v0.4.1-0.20230718164431-9a2bf3000d16 // indirect - github.com/prometheus/common v0.44.0 // indirect - github.com/prometheus/procfs v0.11.1 // indirect - golang.org/x/sys v0.11.0 // indirect - google.golang.org/protobuf v1.31.0 // indirect + github.com/rogpeppe/go-internal v1.10.0 // indirect + gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c // indirect gopkg.in/yaml.v3 v3.0.1 // indirect ) diff --git a/go.sum b/go.sum index 62e7ec6..0fa431b 100644 --- a/go.sum +++ b/go.sum @@ -1,45 +1,25 @@ -github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= -github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw= -github.com/cespare/xxhash/v2 v2.2.0 h1:DC2CZ1Ep5Y4k3ZQ899DldepgrayRUGE6BBZ/cd9Cj44= -github.com/cespare/xxhash/v2 v2.2.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= -github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= -github.com/golang/protobuf v1.5.3 h1:KhyjKVUg7Usr/dYsdSqoFveMYd5ko72D+zANwlG1mmg= -github.com/golang/protobuf v1.5.3/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= -github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38= +github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= +github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= +github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= +github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= -github.com/matttproud/golang_protobuf_extensions v1.0.4 h1:mmDVorXM7PCGKw94cs5zkfA9PSy5pEvNWRP0ET0TIVo= -github.com/matttproud/golang_protobuf_extensions v1.0.4/go.mod h1:BSXmuO+STAnVfrANrmjBb36TMTDstsz7MSK+HVaYKv4= +github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e/go.mod h1:pJLUxLENpZxwdsKMEsNbx1VGcRFpLqf3715MtcvvzbA= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= -github.com/prometheus/client_golang v1.17.0 h1:rl2sfwZMtSthVU752MqfjQozy7blglC+1SOtjMAMh+Q= -github.com/prometheus/client_golang v1.17.0/go.mod h1:VeL+gMmOAxkS2IqfCq0ZmHSL+LjWfWDUmp1mBz9JgUY= -github.com/prometheus/client_model v0.4.1-0.20230718164431-9a2bf3000d16 h1:v7DLqVdK4VrYkVD5diGdl4sxJurKJEMnODWRJlxV9oM= -github.com/prometheus/client_model v0.4.1-0.20230718164431-9a2bf3000d16/go.mod h1:oMQmHW1/JoDwqLtg57MGgP/Fb1CJEYF2imWWhWtMkYU= -github.com/prometheus/common v0.44.0 h1:+5BrQJwiBB9xsMygAB3TNvpQKOwlkc25LbISbrdOOfY= -github.com/prometheus/common v0.44.0/go.mod h1:ofAIvZbQ1e/nugmZGz4/qCb9Ap1VoSTIO7x0VV9VvuY= -github.com/prometheus/procfs v0.11.1 h1:xRC8Iq1yyca5ypa9n1EZnWZkt7dwcoRPQwX/5gwaUuI= -github.com/prometheus/procfs v0.11.1/go.mod h1:eesXgaPo1q7lBpVMoMy0ZOFTth9hBn4W/y0/p/ScXhY= +github.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs= github.com/rogpeppe/go-internal v1.10.0 h1:TMyTOH3F/DB16zRVcYyreMH6GnZZrwQVAoYjRBZyWFQ= +github.com/rogpeppe/go-internal v1.10.0/go.mod h1:UQnix2H7Ngw/k4C5ijL5+65zddjncjaFoBhdsK/akog= github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk= github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= -golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.5.0 h1:60k92dhOjHxJkrqnwsfl8KuaHbn/5dl0lUPUklKo3qE= golang.org/x/sync v0.5.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= -golang.org/x/sys v0.11.0 h1:eG7RXZHdqOJ1i+0lgLgCpSXAp6M3LYlAo6osgSi0xOM= -golang.org/x/sys v0.11.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= -google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= -google.golang.org/protobuf v1.31.0 h1:g0LDEJHgrBl9N9r17Ru3sqWhkIx2NB67okBHPwC7hs8= -google.golang.org/protobuf v1.31.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= +gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= diff --git a/metrics.go b/metrics.go index 1965c40..069d538 100644 --- a/metrics.go +++ b/metrics.go @@ -1,21 +1,24 @@ package puddle import ( - "strconv" "sync/atomic" "time" - - "github.com/prometheus/client_golang/prometheus" ) +// AcquireObserver is called after successful resource acquisition. +// When using AcquireObserver, make sure it executes as possible in +// order not to downgrade overall pool performance. +type AcquireObserver func(d time.Duration, isEmptyAcquire bool) + // Metrics hold puddle metrics. type Metrics struct { acquireCount int64 acquireDuration time.Duration emptyAcquireCount int64 canceledAcquireCount atomic.Int64 - // acquireDurationHistogram can be nil - acquireDurationHistogram *prometheus.HistogramVec + // externalAcquireObserver is an optional callback func that user + // may pass to enable extended monitoring, e.g. prom histogram measurement. + externalAcquireObserver AcquireObserver } func NewMetrics(opts ...MetricsOption) *Metrics { @@ -26,6 +29,10 @@ func NewMetrics(opts ...MetricsOption) *Metrics { return &m } +func (m *Metrics) observeAcquireCancel() { + m.canceledAcquireCount.Add(1) +} + func (m *Metrics) observeAcquireDuration(d time.Duration, isEmptyAcquire bool) { m.acquireCount++ m.acquireDuration += d @@ -33,55 +40,14 @@ func (m *Metrics) observeAcquireDuration(d time.Duration, isEmptyAcquire bool) { m.emptyAcquireCount++ } - if m.acquireDurationHistogram != nil { - m.acquireDurationHistogram. - WithLabelValues(strconv.FormatBool(isEmptyAcquire)). - Observe(float64(d.Nanoseconds())) + if m.externalAcquireObserver != nil { + m.externalAcquireObserver(d, isEmptyAcquire) } } -func (m *Metrics) observeAcquireCancel() { - m.canceledAcquireCount.Add(1) -} - type MetricsOption func(m *Metrics) -// WithAcquireDurationHistogram turns on recording of pool resource acquire duration. -// Histogram metrics can be very expensive for Prometheus to retain and query. -func WithAcquireDurationHistogram(reg prometheus.Registerer, opts ...HistogramOption) MetricsOption { - return func(m *Metrics) { - histOpts := prometheus.HistogramOpts{ - Name: "puddle_acquire_duration_nanoseconds", - Help: "Histogram of a pool resource acquire duration (nanoseconds).", - Buckets: prometheus.DefBuckets, - } - for _, o := range opts { - o(&histOpts) - } - - m.acquireDurationHistogram = prometheus.NewHistogramVec(histOpts, []string{"empty"}) - reg.MustRegister(m.acquireDurationHistogram) - } -} - -// A HistogramOption lets you add options to Histogram metrics using With* funcs. -type HistogramOption func(*prometheus.HistogramOpts) - -// WithHistogramBuckets allows you to specify custom bucket ranges for histograms. -func WithHistogramBuckets(buckets []float64) HistogramOption { - return func(o *prometheus.HistogramOpts) { o.Buckets = buckets } -} - -// WithHistogramConstLabels allows you to add custom ConstLabels to histograms metrics. -func WithHistogramConstLabels(labels prometheus.Labels) HistogramOption { - return func(o *prometheus.HistogramOpts) { - o.ConstLabels = labels - } -} - -// WithHistogramSubsystem allows you to add a Subsystem to histograms metrics. -func WithHistogramSubsystem(subsystem string) HistogramOption { - return func(o *prometheus.HistogramOpts) { - o.Subsystem = subsystem - } +// WithExternalAcquireObserver sets optional callback function for duration observation. +func WithExternalAcquireObserver(observer AcquireObserver) MetricsOption { + return func(m *Metrics) { m.externalAcquireObserver = observer } } From e0ae377deaf8f5c4a68a9ea8c93e3fdb644ffd44 Mon Sep 17 00:00:00 2001 From: sashayakovtseva Date: Mon, 4 Dec 2023 15:58:03 +0300 Subject: [PATCH 5/7] Revert deps update Signed-off-by: sashayakovtseva --- go.mod | 7 ++----- go.sum | 30 ++++++++++++------------------ 2 files changed, 14 insertions(+), 23 deletions(-) diff --git a/go.mod b/go.mod index bd15a7c..b66cc9c 100644 --- a/go.mod +++ b/go.mod @@ -3,15 +3,12 @@ module github.com/jackc/puddle/v2 go 1.19 require ( - github.com/stretchr/testify v1.8.4 - golang.org/x/sync v0.5.0 + github.com/stretchr/testify v1.8.1 + golang.org/x/sync v0.1.0 ) require ( github.com/davecgh/go-spew v1.1.1 // indirect - github.com/kr/pretty v0.3.1 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect - github.com/rogpeppe/go-internal v1.10.0 // indirect - gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c // indirect gopkg.in/yaml.v3 v3.0.1 // indirect ) diff --git a/go.sum b/go.sum index 0fa431b..96e82f8 100644 --- a/go.sum +++ b/go.sum @@ -1,25 +1,19 @@ -github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= +github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= -github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= -github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= -github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= -github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= -github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= -github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= -github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e/go.mod h1:pJLUxLENpZxwdsKMEsNbx1VGcRFpLqf3715MtcvvzbA= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= -github.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs= -github.com/rogpeppe/go-internal v1.10.0 h1:TMyTOH3F/DB16zRVcYyreMH6GnZZrwQVAoYjRBZyWFQ= -github.com/rogpeppe/go-internal v1.10.0/go.mod h1:UQnix2H7Ngw/k4C5ijL5+65zddjncjaFoBhdsK/akog= -github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk= -github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= -golang.org/x/sync v0.5.0 h1:60k92dhOjHxJkrqnwsfl8KuaHbn/5dl0lUPUklKo3qE= -golang.org/x/sync v0.5.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= +github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= +github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= +github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= +github.com/stretchr/testify v1.8.1 h1:w7B6lhMri9wdJUVmEZPGGhZzrYTPvgJArz7wNPgYKsk= +github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= +golang.org/x/sync v0.1.0 h1:wsuoTGHzEhffawBOhz5CYhcrV4IdKZbEyZjBMuTp12o= +golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= -gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= +gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= From 0d575be1b1aedc15bbe521a1949407e0ff8fc011 Mon Sep 17 00:00:00 2001 From: sashayakovtseva Date: Mon, 4 Dec 2023 16:21:44 +0300 Subject: [PATCH 6/7] Fix typos Signed-off-by: sashayakovtseva --- pool.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pool.go b/pool.go index a9bcd41..50c97d4 100644 --- a/pool.go +++ b/pool.go @@ -413,7 +413,7 @@ func (p *Pool[T]) initResourceValue(ctx context.Context, res *Resource[T]) (*Res // The resource won't be acquired because its // construction failed. We have to allow someone else to - // take that resouce. + // take that resource. p.acquireSem.Release(1) p.mux.Unlock() @@ -651,7 +651,7 @@ func (p *Pool[T]) Reset() { } } -// releaseAcquiredResource returns res to the the pool. +// releaseAcquiredResource returns res to the pool. func (p *Pool[T]) releaseAcquiredResource(res *Resource[T], lastUsedNano int64) { p.mux.Lock() defer p.mux.Unlock() From d34710dc4de666a8580dc10fe284f816590f6d57 Mon Sep 17 00:00:00 2001 From: sashayakovtseva Date: Mon, 4 Dec 2023 16:21:54 +0300 Subject: [PATCH 7/7] Align metrics struct Signed-off-by: sashayakovtseva --- metrics.go | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/metrics.go b/metrics.go index 069d538..4cf7353 100644 --- a/metrics.go +++ b/metrics.go @@ -12,13 +12,14 @@ type AcquireObserver func(d time.Duration, isEmptyAcquire bool) // Metrics hold puddle metrics. type Metrics struct { + // externalAcquireObserver is an optional callback func that user + // may pass to enable extended monitoring, e.g. prom histogram measurement. + externalAcquireObserver AcquireObserver + acquireCount int64 acquireDuration time.Duration emptyAcquireCount int64 canceledAcquireCount atomic.Int64 - // externalAcquireObserver is an optional callback func that user - // may pass to enable extended monitoring, e.g. prom histogram measurement. - externalAcquireObserver AcquireObserver } func NewMetrics(opts ...MetricsOption) *Metrics { @@ -33,6 +34,7 @@ func (m *Metrics) observeAcquireCancel() { m.canceledAcquireCount.Add(1) } +// observeAcquireDuration is not thread safe. func (m *Metrics) observeAcquireDuration(d time.Duration, isEmptyAcquire bool) { m.acquireCount++ m.acquireDuration += d