From 6b7b9dc97702c554f6fa8a62b51190f0c1e973f1 Mon Sep 17 00:00:00 2001 From: Arpad Ryszka Date: Sun, 10 May 2026 21:17:54 +0200 Subject: [PATCH] handle uninitialized state --- Makefile | 6 +++--- lib.go | 38 +++++++++++++++++++++++++++++++++++++- 2 files changed, 40 insertions(+), 4 deletions(-) diff --git a/Makefile b/Makefile index 438ffb3..9cb7403 100644 --- a/Makefile +++ b/Makefile @@ -9,13 +9,13 @@ fmt: $(sources) go fmt check: $(sources) - go test -count 1 + go test -v -count 1 race: $(source) - go test -count 1 -race + go test -v -count 1 -race .cover: $(sources) - go test -count 1 -coverprofile .cover + go test -v -count 1 -coverprofile .cover cover: .cover go tool cover -func .cover diff --git a/lib.go b/lib.go index 0a6ebb5..85c386e 100644 --- a/lib.go +++ b/lib.go @@ -158,10 +158,13 @@ type Pool[R any] struct { pool pool[R] } -// ErrNoItems is returned on Get calls when the pool does not enough items and it was initialized without an +// ErrNoItems is returned on Get calls when the pool does not have enough items and it was initialized without an // allocate function. var ErrNoItems = errors.New("not enough items in the pool") +// ErrUninitialized is returned when the pool was not initialized. +var ErrUninitialized = errors.New("pool uninitialized") + // String returns the string representation of the EventType binary flag, including all the flags that are set. func (et EventType) String() string { var s []string @@ -283,6 +286,10 @@ func Make[R any](alloc func() (R, error), free func(R), o Options) Pool[R] { // function returns an error, it returns the available items and that error. If events were configured, GetN // triggers a GetOperation event. func (p Pool[R]) GetN(n int) ([]R, error) { + if p.pool.state == nil { + return nil, ErrUninitialized + } + return p.pool.get(n) } @@ -290,6 +297,11 @@ func (p Pool[R]) GetN(n int) ([]R, error) { // ErrEmpty. If the pool is empty, and the allocation function returns an error, it returns that error. If // events were configured, Get triggers a GetOperation event. func (p Pool[R]) Get() (R, error) { + if p.pool.state == nil { + var r R + return r, ErrUninitialized + } + r, err := p.pool.get(1) if err != nil { var rr R @@ -306,6 +318,10 @@ func (p Pool[R]) Get() (R, error) { // sudden drop in the number of active items. If the pool needs to be prewarmed, or prepared for an expected // spike of traffic, consider using the Load method. func (p Pool[R]) Put(i ...R) { + if p.pool.state == nil { + return + } + p.pool.put(i...) } @@ -315,11 +331,19 @@ func (p Pool[R]) Put(i ...R) { // shrinking algorithm, it may work more consistently, if the algorithm is notified about the change in the // active items. The other purpose is to allow the pool to reflect these cases in the events and the stats. func (p Pool[R]) DropN(n int) { + if p.pool.state == nil { + return + } + p.pool.drop(n) } // Drop is like DropN, but for a single item. func (p Pool[R]) Drop() { + if p.pool.state == nil { + return + } + p.pool.drop(1) } @@ -327,17 +351,29 @@ func (p Pool[R]) Drop() { // It can be useful in scenarios where prewarming or preparing for a sudden traffic spike is necessary. If // events were configured, it triggers a LoadOperation event. func (p Pool[R]) Load(i []R) { + if p.pool.state == nil { + return + } + p.pool.load(i) } // Stats returns statistics about the current state of the pool. It contains the current number of active/idle // items, and perpetual counters for the various pool operations. func (p Pool[R]) Stats() Stats { + if p.pool.state == nil { + return Stats{} + } + return p.pool.stats() } // Free releases all idle items in the pool. While the pool stays operational, Free is meant to be used when the // pool is not required anymore. func (p Pool[R]) Free() { + if p.pool.state == nil { + return + } + p.pool.freePool() }