NewPool takes Config
This allows for backwards compatible additions. No features are planned but this would make it easier if they are added.
This commit is contained in:
@@ -30,7 +30,7 @@ destructor := func(value net.Conn) {
|
|||||||
}
|
}
|
||||||
maxPoolSize := 10
|
maxPoolSize := 10
|
||||||
|
|
||||||
pool := puddle.NewPool(constructor, destructor, maxPoolSize)
|
pool := puddle.NewPool[net.Conn](&puddle.Config[int]{Constructor: constructor, Destructor: destructor, MaxSize: maxPoolSize})
|
||||||
|
|
||||||
// Acquire resource from the pool.
|
// Acquire resource from the pool.
|
||||||
res, err := pool.Acquire(context.Background())
|
res, err := pool.Acquire(context.Background())
|
||||||
|
|||||||
@@ -132,19 +132,25 @@ type Pool[T any] struct {
|
|||||||
closed bool
|
closed bool
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type Config[T any] struct {
|
||||||
|
Constructor Constructor[T]
|
||||||
|
Destructor Destructor[T]
|
||||||
|
MaxSize int32
|
||||||
|
}
|
||||||
|
|
||||||
// NewPool creates a new pool. Panics if maxSize is less than 1.
|
// NewPool creates a new pool. Panics if maxSize is less than 1.
|
||||||
func NewPool[T any](constructor Constructor[T], destructor Destructor[T], maxSize int32) *Pool[T] {
|
func NewPool[T any](config *Config[T]) (*Pool[T], error) {
|
||||||
if maxSize < 1 {
|
if config.MaxSize < 1 {
|
||||||
panic("maxSize is less than 1")
|
return nil, errors.New("MaxSize must be >= 1")
|
||||||
}
|
}
|
||||||
|
|
||||||
return &Pool[T]{
|
return &Pool[T]{
|
||||||
cond: sync.NewCond(new(sync.Mutex)),
|
cond: sync.NewCond(new(sync.Mutex)),
|
||||||
destructWG: &sync.WaitGroup{},
|
destructWG: &sync.WaitGroup{},
|
||||||
maxSize: maxSize,
|
maxSize: config.MaxSize,
|
||||||
constructor: constructor,
|
constructor: config.Constructor,
|
||||||
destructor: destructor,
|
destructor: config.Destructor,
|
||||||
}
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Close destroys all resources in the pool and rejects future Acquire calls.
|
// Close destroys all resources in the pool and rejects future Acquire calls.
|
||||||
|
|||||||
+91
-48
@@ -53,13 +53,19 @@ func stubDestructor(int) {}
|
|||||||
|
|
||||||
func TestNewPoolRequiresMaxSizeGreaterThan0(t *testing.T) {
|
func TestNewPoolRequiresMaxSizeGreaterThan0(t *testing.T) {
|
||||||
constructor, _ := createConstructor()
|
constructor, _ := createConstructor()
|
||||||
assert.Panics(t, func() { puddle.NewPool(constructor, stubDestructor, -1) })
|
pool, err := puddle.NewPool(&puddle.Config[int]{Constructor: constructor, Destructor: stubDestructor, MaxSize: -1})
|
||||||
assert.Panics(t, func() { puddle.NewPool(constructor, stubDestructor, 0) })
|
assert.Nil(t, pool)
|
||||||
|
assert.Error(t, err)
|
||||||
|
|
||||||
|
pool, err = puddle.NewPool(&puddle.Config[int]{Constructor: constructor, Destructor: stubDestructor, MaxSize: 0})
|
||||||
|
assert.Nil(t, pool)
|
||||||
|
assert.Error(t, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestPoolAcquireCreatesResourceWhenNoneIdle(t *testing.T) {
|
func TestPoolAcquireCreatesResourceWhenNoneIdle(t *testing.T) {
|
||||||
constructor, _ := createConstructor()
|
constructor, _ := createConstructor()
|
||||||
pool := puddle.NewPool(constructor, stubDestructor, 10)
|
pool, err := puddle.NewPool(&puddle.Config[int]{Constructor: constructor, Destructor: stubDestructor, MaxSize: 10})
|
||||||
|
require.NoError(t, err)
|
||||||
defer pool.Close()
|
defer pool.Close()
|
||||||
|
|
||||||
res, err := pool.Acquire(context.Background())
|
res, err := pool.Acquire(context.Background())
|
||||||
@@ -71,7 +77,8 @@ func TestPoolAcquireCreatesResourceWhenNoneIdle(t *testing.T) {
|
|||||||
|
|
||||||
func TestPoolAcquireDoesNotCreatesResourceWhenItWouldExceedMaxSize(t *testing.T) {
|
func TestPoolAcquireDoesNotCreatesResourceWhenItWouldExceedMaxSize(t *testing.T) {
|
||||||
constructor, createCounter := createConstructor()
|
constructor, createCounter := createConstructor()
|
||||||
pool := puddle.NewPool(constructor, stubDestructor, 1)
|
pool, err := puddle.NewPool(&puddle.Config[int]{Constructor: constructor, Destructor: stubDestructor, MaxSize: 1})
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
wg := &sync.WaitGroup{}
|
wg := &sync.WaitGroup{}
|
||||||
|
|
||||||
@@ -96,7 +103,8 @@ func TestPoolAcquireDoesNotCreatesResourceWhenItWouldExceedMaxSize(t *testing.T)
|
|||||||
|
|
||||||
func TestPoolAcquireWithCancellableContext(t *testing.T) {
|
func TestPoolAcquireWithCancellableContext(t *testing.T) {
|
||||||
constructor, createCounter := createConstructor()
|
constructor, createCounter := createConstructor()
|
||||||
pool := puddle.NewPool(constructor, stubDestructor, 1)
|
pool, err := puddle.NewPool(&puddle.Config[int]{Constructor: constructor, Destructor: stubDestructor, MaxSize: 1})
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
wg := &sync.WaitGroup{}
|
wg := &sync.WaitGroup{}
|
||||||
|
|
||||||
@@ -126,7 +134,8 @@ func TestPoolAcquireReturnsErrorFromFailedResourceCreate(t *testing.T) {
|
|||||||
constructor := func(ctx context.Context) (int, error) {
|
constructor := func(ctx context.Context) (int, error) {
|
||||||
return 0, errCreateFailed
|
return 0, errCreateFailed
|
||||||
}
|
}
|
||||||
pool := puddle.NewPool(constructor, stubDestructor, 10)
|
pool, err := puddle.NewPool(&puddle.Config[int]{Constructor: constructor, Destructor: stubDestructor, MaxSize: 10})
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
res, err := pool.Acquire(context.Background())
|
res, err := pool.Acquire(context.Background())
|
||||||
assert.Equal(t, errCreateFailed, err)
|
assert.Equal(t, errCreateFailed, err)
|
||||||
@@ -141,13 +150,14 @@ func TestPoolAcquireCreatesResourceRespectingContext(t *testing.T) {
|
|||||||
time.Sleep(10 * time.Millisecond)
|
time.Sleep(10 * time.Millisecond)
|
||||||
return 1, nil
|
return 1, nil
|
||||||
}
|
}
|
||||||
pool := puddle.NewPool(constructor, stubDestructor, 1)
|
pool, err := puddle.NewPool(&puddle.Config[int]{Constructor: constructor, Destructor: stubDestructor, MaxSize: 1})
|
||||||
|
require.NoError(t, err)
|
||||||
defer pool.Close()
|
defer pool.Close()
|
||||||
|
|
||||||
var ctx context.Context
|
var ctx context.Context
|
||||||
ctx, cancel = context.WithCancel(context.Background())
|
ctx, cancel = context.WithCancel(context.Background())
|
||||||
defer cancel()
|
defer cancel()
|
||||||
_, err := pool.Acquire(ctx)
|
_, err = pool.Acquire(ctx)
|
||||||
assert.ErrorIs(t, err, context.Canceled)
|
assert.ErrorIs(t, err, context.Canceled)
|
||||||
|
|
||||||
// wait for the constructor to sleep and then for the resource to be added back
|
// wait for the constructor to sleep and then for the resource to be added back
|
||||||
@@ -161,7 +171,8 @@ func TestPoolAcquireCreatesResourceRespectingContext(t *testing.T) {
|
|||||||
|
|
||||||
func TestPoolAcquireReusesResources(t *testing.T) {
|
func TestPoolAcquireReusesResources(t *testing.T) {
|
||||||
constructor, createCounter := createConstructor()
|
constructor, createCounter := createConstructor()
|
||||||
pool := puddle.NewPool(constructor, stubDestructor, 10)
|
pool, err := puddle.NewPool(&puddle.Config[int]{Constructor: constructor, Destructor: stubDestructor, MaxSize: 10})
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
res, err := pool.Acquire(context.Background())
|
res, err := pool.Acquire(context.Background())
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
@@ -180,7 +191,8 @@ func TestPoolAcquireReusesResources(t *testing.T) {
|
|||||||
|
|
||||||
func TestPoolTryAcquire(t *testing.T) {
|
func TestPoolTryAcquire(t *testing.T) {
|
||||||
constructor, createCounter := createConstructor()
|
constructor, createCounter := createConstructor()
|
||||||
pool := puddle.NewPool(constructor, stubDestructor, 1)
|
pool, err := puddle.NewPool(&puddle.Config[int]{Constructor: constructor, Destructor: stubDestructor, MaxSize: 1})
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
// Pool is initially empty so TryAcquire fails but starts construction of resource in the background.
|
// Pool is initially empty so TryAcquire fails but starts construction of resource in the background.
|
||||||
res, err := pool.TryAcquire(context.Background())
|
res, err := pool.TryAcquire(context.Background())
|
||||||
@@ -204,7 +216,8 @@ func TestPoolTryAcquire(t *testing.T) {
|
|||||||
|
|
||||||
func TestPoolTryAcquireReturnsErrorWhenPoolIsClosed(t *testing.T) {
|
func TestPoolTryAcquireReturnsErrorWhenPoolIsClosed(t *testing.T) {
|
||||||
constructor, _ := createConstructor()
|
constructor, _ := createConstructor()
|
||||||
pool := puddle.NewPool(constructor, stubDestructor, 10)
|
pool, err := puddle.NewPool(&puddle.Config[int]{Constructor: constructor, Destructor: stubDestructor, MaxSize: 10})
|
||||||
|
require.NoError(t, err)
|
||||||
pool.Close()
|
pool.Close()
|
||||||
|
|
||||||
res, err := pool.TryAcquire(context.Background())
|
res, err := pool.TryAcquire(context.Background())
|
||||||
@@ -217,7 +230,8 @@ func TestPoolTryAcquireWithFailedResourceCreate(t *testing.T) {
|
|||||||
constructor := func(ctx context.Context) (int, error) {
|
constructor := func(ctx context.Context) (int, error) {
|
||||||
return 0, errCreateFailed
|
return 0, errCreateFailed
|
||||||
}
|
}
|
||||||
pool := puddle.NewPool(constructor, stubDestructor, 10)
|
pool, err := puddle.NewPool(&puddle.Config[int]{Constructor: constructor, Destructor: stubDestructor, MaxSize: 10})
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
res, err := pool.TryAcquire(context.Background())
|
res, err := pool.TryAcquire(context.Background())
|
||||||
require.EqualError(t, err, puddle.ErrNotAvailable.Error())
|
require.EqualError(t, err, puddle.ErrNotAvailable.Error())
|
||||||
@@ -226,7 +240,8 @@ func TestPoolTryAcquireWithFailedResourceCreate(t *testing.T) {
|
|||||||
|
|
||||||
func TestPoolAcquireNilContextDoesNotLeavePoolLocked(t *testing.T) {
|
func TestPoolAcquireNilContextDoesNotLeavePoolLocked(t *testing.T) {
|
||||||
constructor, createCounter := createConstructor()
|
constructor, createCounter := createConstructor()
|
||||||
pool := puddle.NewPool(constructor, stubDestructor, 10)
|
pool, err := puddle.NewPool(&puddle.Config[int]{Constructor: constructor, Destructor: stubDestructor, MaxSize: 10})
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
assert.Panics(t, func() { pool.Acquire(nil) })
|
assert.Panics(t, func() { pool.Acquire(nil) })
|
||||||
|
|
||||||
@@ -242,7 +257,8 @@ func TestPoolAcquireContextAlreadyCanceled(t *testing.T) {
|
|||||||
constructor := func(ctx context.Context) (int, error) {
|
constructor := func(ctx context.Context) (int, error) {
|
||||||
panic("should never be called")
|
panic("should never be called")
|
||||||
}
|
}
|
||||||
pool := puddle.NewPool(constructor, stubDestructor, 10)
|
pool, err := puddle.NewPool(&puddle.Config[int]{Constructor: constructor, Destructor: stubDestructor, MaxSize: 10})
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
ctx, cancel := context.WithCancel(context.Background())
|
ctx, cancel := context.WithCancel(context.Background())
|
||||||
cancel()
|
cancel()
|
||||||
@@ -265,7 +281,8 @@ func TestPoolAcquireContextCanceledDuringCreate(t *testing.T) {
|
|||||||
}
|
}
|
||||||
return constructorCalls.Next(), nil
|
return constructorCalls.Next(), nil
|
||||||
}
|
}
|
||||||
pool := puddle.NewPool(constructor, stubDestructor, 10)
|
pool, err := puddle.NewPool(&puddle.Config[int]{Constructor: constructor, Destructor: stubDestructor, MaxSize: 10})
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
res, err := pool.Acquire(ctx)
|
res, err := pool.Acquire(ctx)
|
||||||
assert.Equal(t, context.Canceled, err)
|
assert.Equal(t, context.Canceled, err)
|
||||||
@@ -274,11 +291,11 @@ func TestPoolAcquireContextCanceledDuringCreate(t *testing.T) {
|
|||||||
|
|
||||||
func TestPoolAcquireAllIdle(t *testing.T) {
|
func TestPoolAcquireAllIdle(t *testing.T) {
|
||||||
constructor, _ := createConstructor()
|
constructor, _ := createConstructor()
|
||||||
pool := puddle.NewPool(constructor, stubDestructor, 10)
|
pool, err := puddle.NewPool(&puddle.Config[int]{Constructor: constructor, Destructor: stubDestructor, MaxSize: 10})
|
||||||
|
require.NoError(t, err)
|
||||||
defer pool.Close()
|
defer pool.Close()
|
||||||
|
|
||||||
resources := make([]*puddle.Resource[int], 4)
|
resources := make([]*puddle.Resource[int], 4)
|
||||||
var err error
|
|
||||||
|
|
||||||
resources[0], err = pool.Acquire(context.Background())
|
resources[0], err = pool.Acquire(context.Background())
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
@@ -311,18 +328,18 @@ func TestPoolAcquireAllIdle(t *testing.T) {
|
|||||||
|
|
||||||
func TestPoolAcquireAllIdleWhenClosedIsNil(t *testing.T) {
|
func TestPoolAcquireAllIdleWhenClosedIsNil(t *testing.T) {
|
||||||
constructor, _ := createConstructor()
|
constructor, _ := createConstructor()
|
||||||
pool := puddle.NewPool(constructor, stubDestructor, 10)
|
pool, err := puddle.NewPool(&puddle.Config[int]{Constructor: constructor, Destructor: stubDestructor, MaxSize: 10})
|
||||||
|
require.NoError(t, err)
|
||||||
pool.Close()
|
pool.Close()
|
||||||
assert.Nil(t, pool.AcquireAllIdle())
|
assert.Nil(t, pool.AcquireAllIdle())
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestPoolCreateResource(t *testing.T) {
|
func TestPoolCreateResource(t *testing.T) {
|
||||||
constructor, counter := createConstructor()
|
constructor, counter := createConstructor()
|
||||||
pool := puddle.NewPool(constructor, stubDestructor, 10)
|
pool, err := puddle.NewPool(&puddle.Config[int]{Constructor: constructor, Destructor: stubDestructor, MaxSize: 10})
|
||||||
|
require.NoError(t, err)
|
||||||
defer pool.Close()
|
defer pool.Close()
|
||||||
|
|
||||||
var err error
|
|
||||||
|
|
||||||
err = pool.CreateResource(context.Background())
|
err = pool.CreateResource(context.Background())
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
@@ -345,17 +362,19 @@ func TestPoolCreateResourceReturnsErrorFromFailedResourceCreate(t *testing.T) {
|
|||||||
constructor := func(ctx context.Context) (int, error) {
|
constructor := func(ctx context.Context) (int, error) {
|
||||||
return 0, errCreateFailed
|
return 0, errCreateFailed
|
||||||
}
|
}
|
||||||
pool := puddle.NewPool(constructor, stubDestructor, 10)
|
pool, err := puddle.NewPool(&puddle.Config[int]{Constructor: constructor, Destructor: stubDestructor, MaxSize: 10})
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
err := pool.CreateResource(context.Background())
|
err = pool.CreateResource(context.Background())
|
||||||
assert.Equal(t, errCreateFailed, err)
|
assert.Equal(t, errCreateFailed, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestPoolCreateResourceReturnsErrorWhenAlreadyClosed(t *testing.T) {
|
func TestPoolCreateResourceReturnsErrorWhenAlreadyClosed(t *testing.T) {
|
||||||
constructor, _ := createConstructor()
|
constructor, _ := createConstructor()
|
||||||
pool := puddle.NewPool(constructor, stubDestructor, 10)
|
pool, err := puddle.NewPool(&puddle.Config[int]{Constructor: constructor, Destructor: stubDestructor, MaxSize: 10})
|
||||||
|
require.NoError(t, err)
|
||||||
pool.Close()
|
pool.Close()
|
||||||
err := pool.CreateResource(context.Background())
|
err = pool.CreateResource(context.Background())
|
||||||
assert.Equal(t, puddle.ErrClosedPool, err)
|
assert.Equal(t, puddle.ErrClosedPool, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -366,7 +385,8 @@ func TestPoolCreateResourceReturnsErrorWhenClosedWhileCreatingResource(t *testin
|
|||||||
time.Sleep(500 * time.Millisecond)
|
time.Sleep(500 * time.Millisecond)
|
||||||
return 123, nil
|
return 123, nil
|
||||||
}
|
}
|
||||||
pool := puddle.NewPool(constructor, stubDestructor, 10)
|
pool, err := puddle.NewPool(&puddle.Config[int]{Constructor: constructor, Destructor: stubDestructor, MaxSize: 10})
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
acquireErrChan := make(chan error)
|
acquireErrChan := make(chan error)
|
||||||
go func() {
|
go func() {
|
||||||
@@ -377,7 +397,7 @@ func TestPoolCreateResourceReturnsErrorWhenClosedWhileCreatingResource(t *testin
|
|||||||
time.Sleep(250 * time.Millisecond)
|
time.Sleep(250 * time.Millisecond)
|
||||||
pool.Close()
|
pool.Close()
|
||||||
|
|
||||||
err := <-acquireErrChan
|
err = <-acquireErrChan
|
||||||
assert.Equal(t, puddle.ErrClosedPool, err)
|
assert.Equal(t, puddle.ErrClosedPool, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -389,7 +409,8 @@ func TestPoolCloseClosesAllIdleResources(t *testing.T) {
|
|||||||
destructorCalls.Next()
|
destructorCalls.Next()
|
||||||
}
|
}
|
||||||
|
|
||||||
p := puddle.NewPool(constructor, destructor, 10)
|
p, err := puddle.NewPool(&puddle.Config[int]{Constructor: constructor, Destructor: destructor, MaxSize: 10})
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
resources := make([]*puddle.Resource[int], 4)
|
resources := make([]*puddle.Resource[int], 4)
|
||||||
for i := range resources {
|
for i := range resources {
|
||||||
@@ -414,7 +435,8 @@ func TestPoolCloseBlocksUntilAllResourcesReleasedAndClosed(t *testing.T) {
|
|||||||
destructorCalls.Next()
|
destructorCalls.Next()
|
||||||
}
|
}
|
||||||
|
|
||||||
p := puddle.NewPool(constructor, destructor, 10)
|
p, err := puddle.NewPool(&puddle.Config[int]{Constructor: constructor, Destructor: destructor, MaxSize: 10})
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
resources := make([]*puddle.Resource[int], 4)
|
resources := make([]*puddle.Resource[int], 4)
|
||||||
for i := range resources {
|
for i := range resources {
|
||||||
@@ -437,7 +459,8 @@ func TestPoolCloseBlocksUntilAllResourcesReleasedAndClosed(t *testing.T) {
|
|||||||
func TestPoolCloseIsSafeToCallMultipleTimes(t *testing.T) {
|
func TestPoolCloseIsSafeToCallMultipleTimes(t *testing.T) {
|
||||||
constructor, _ := createConstructor()
|
constructor, _ := createConstructor()
|
||||||
|
|
||||||
p := puddle.NewPool(constructor, stubDestructor, 10)
|
p, err := puddle.NewPool(&puddle.Config[int]{Constructor: constructor, Destructor: stubDestructor, MaxSize: 10})
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
p.Close()
|
p.Close()
|
||||||
p.Close()
|
p.Close()
|
||||||
@@ -451,7 +474,8 @@ func TestPoolResetDestroysAllIdleResources(t *testing.T) {
|
|||||||
destructorCalls.Next()
|
destructorCalls.Next()
|
||||||
}
|
}
|
||||||
|
|
||||||
p := puddle.NewPool(constructor, destructor, 10)
|
p, err := puddle.NewPool(&puddle.Config[int]{Constructor: constructor, Destructor: destructor, MaxSize: 10})
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
resources := make([]*puddle.Resource[int], 4)
|
resources := make([]*puddle.Resource[int], 4)
|
||||||
for i := range resources {
|
for i := range resources {
|
||||||
@@ -488,7 +512,8 @@ func TestPoolResetDestroysCheckedOutResourcesOnReturn(t *testing.T) {
|
|||||||
destructorCalls.Next()
|
destructorCalls.Next()
|
||||||
}
|
}
|
||||||
|
|
||||||
p := puddle.NewPool(constructor, destructor, 10)
|
p, err := puddle.NewPool(&puddle.Config[int]{Constructor: constructor, Destructor: destructor, MaxSize: 10})
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
resources := make([]*puddle.Resource[int], 4)
|
resources := make([]*puddle.Resource[int], 4)
|
||||||
for i := range resources {
|
for i := range resources {
|
||||||
@@ -535,7 +560,8 @@ func TestPoolStatResources(t *testing.T) {
|
|||||||
|
|
||||||
return constructorCalls.Next(), nil
|
return constructorCalls.Next(), nil
|
||||||
}
|
}
|
||||||
pool := puddle.NewPool(constructor, stubDestructor, 10)
|
pool, err := puddle.NewPool(&puddle.Config[int]{Constructor: constructor, Destructor: stubDestructor, MaxSize: 10})
|
||||||
|
require.NoError(t, err)
|
||||||
defer pool.Close()
|
defer pool.Close()
|
||||||
|
|
||||||
resAcquired, err := pool.Acquire(context.Background())
|
resAcquired, err := pool.Acquire(context.Background())
|
||||||
@@ -575,7 +601,8 @@ func TestPoolStatSuccessfulAcquireCounters(t *testing.T) {
|
|||||||
time.Sleep(time.Nanosecond)
|
time.Sleep(time.Nanosecond)
|
||||||
return constructor(ctx)
|
return constructor(ctx)
|
||||||
}
|
}
|
||||||
pool := puddle.NewPool(sleepConstructor, stubDestructor, 1)
|
pool, err := puddle.NewPool(&puddle.Config[int]{Constructor: sleepConstructor, Destructor: stubDestructor, MaxSize: 1})
|
||||||
|
require.NoError(t, err)
|
||||||
defer pool.Close()
|
defer pool.Close()
|
||||||
|
|
||||||
res, err := pool.Acquire(context.Background())
|
res, err := pool.Acquire(context.Background())
|
||||||
@@ -621,12 +648,13 @@ func TestPoolStatSuccessfulAcquireCounters(t *testing.T) {
|
|||||||
|
|
||||||
func TestPoolStatCanceledAcquireBeforeStart(t *testing.T) {
|
func TestPoolStatCanceledAcquireBeforeStart(t *testing.T) {
|
||||||
constructor, _ := createConstructor()
|
constructor, _ := createConstructor()
|
||||||
pool := puddle.NewPool(constructor, stubDestructor, 1)
|
pool, err := puddle.NewPool(&puddle.Config[int]{Constructor: constructor, Destructor: stubDestructor, MaxSize: 1})
|
||||||
|
require.NoError(t, err)
|
||||||
defer pool.Close()
|
defer pool.Close()
|
||||||
|
|
||||||
ctx, cancel := context.WithCancel(context.Background())
|
ctx, cancel := context.WithCancel(context.Background())
|
||||||
cancel()
|
cancel()
|
||||||
_, err := pool.Acquire(ctx)
|
_, err = pool.Acquire(ctx)
|
||||||
require.Equal(t, context.Canceled, err)
|
require.Equal(t, context.Canceled, err)
|
||||||
|
|
||||||
stat := pool.Stat()
|
stat := pool.Stat()
|
||||||
@@ -640,12 +668,13 @@ func TestPoolStatCanceledAcquireDuringCreate(t *testing.T) {
|
|||||||
return 0, ctx.Err()
|
return 0, ctx.Err()
|
||||||
}
|
}
|
||||||
|
|
||||||
pool := puddle.NewPool(constructor, stubDestructor, 1)
|
pool, err := puddle.NewPool(&puddle.Config[int]{Constructor: constructor, Destructor: stubDestructor, MaxSize: 1})
|
||||||
|
require.NoError(t, err)
|
||||||
defer pool.Close()
|
defer pool.Close()
|
||||||
|
|
||||||
ctx, cancel := context.WithCancel(context.Background())
|
ctx, cancel := context.WithCancel(context.Background())
|
||||||
time.AfterFunc(50*time.Millisecond, cancel)
|
time.AfterFunc(50*time.Millisecond, cancel)
|
||||||
_, err := pool.Acquire(ctx)
|
_, err = pool.Acquire(ctx)
|
||||||
require.Equal(t, context.Canceled, err)
|
require.Equal(t, context.Canceled, err)
|
||||||
|
|
||||||
// sleep to give the constructor goroutine time to mark cancelled
|
// sleep to give the constructor goroutine time to mark cancelled
|
||||||
@@ -658,7 +687,8 @@ func TestPoolStatCanceledAcquireDuringCreate(t *testing.T) {
|
|||||||
|
|
||||||
func TestPoolStatCanceledAcquireDuringWait(t *testing.T) {
|
func TestPoolStatCanceledAcquireDuringWait(t *testing.T) {
|
||||||
constructor, _ := createConstructor()
|
constructor, _ := createConstructor()
|
||||||
pool := puddle.NewPool(constructor, stubDestructor, 1)
|
pool, err := puddle.NewPool(&puddle.Config[int]{Constructor: constructor, Destructor: stubDestructor, MaxSize: 1})
|
||||||
|
require.NoError(t, err)
|
||||||
defer pool.Close()
|
defer pool.Close()
|
||||||
|
|
||||||
res, err := pool.Acquire(context.Background())
|
res, err := pool.Acquire(context.Background())
|
||||||
@@ -683,7 +713,8 @@ func TestResourceHijackRemovesResourceFromPoolButDoesNotDestroy(t *testing.T) {
|
|||||||
destructorCalls.Next()
|
destructorCalls.Next()
|
||||||
}
|
}
|
||||||
|
|
||||||
pool := puddle.NewPool(constructor, destructor, 10)
|
pool, err := puddle.NewPool(&puddle.Config[int]{Constructor: constructor, Destructor: destructor, MaxSize: 10})
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
res, err := pool.Acquire(context.Background())
|
res, err := pool.Acquire(context.Background())
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
@@ -702,7 +733,8 @@ func TestResourceHijackRemovesResourceFromPoolButDoesNotDestroy(t *testing.T) {
|
|||||||
|
|
||||||
func TestResourceDestroyRemovesResourceFromPool(t *testing.T) {
|
func TestResourceDestroyRemovesResourceFromPool(t *testing.T) {
|
||||||
constructor, _ := createConstructor()
|
constructor, _ := createConstructor()
|
||||||
pool := puddle.NewPool(constructor, stubDestructor, 10)
|
pool, err := puddle.NewPool(&puddle.Config[int]{Constructor: constructor, Destructor: stubDestructor, MaxSize: 10})
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
res, err := pool.Acquire(context.Background())
|
res, err := pool.Acquire(context.Background())
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
@@ -722,7 +754,8 @@ func TestResourceDestroyRemovesResourceFromPool(t *testing.T) {
|
|||||||
|
|
||||||
func TestResourceLastUsageTimeTracking(t *testing.T) {
|
func TestResourceLastUsageTimeTracking(t *testing.T) {
|
||||||
constructor, _ := createConstructor()
|
constructor, _ := createConstructor()
|
||||||
pool := puddle.NewPool(constructor, stubDestructor, 1)
|
pool, err := puddle.NewPool(&puddle.Config[int]{Constructor: constructor, Destructor: stubDestructor, MaxSize: 1})
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
res, err := pool.Acquire(context.Background())
|
res, err := pool.Acquire(context.Background())
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
@@ -756,7 +789,8 @@ func TestResourceLastUsageTimeTracking(t *testing.T) {
|
|||||||
|
|
||||||
func TestResourcePanicsOnUsageWhenNotAcquired(t *testing.T) {
|
func TestResourcePanicsOnUsageWhenNotAcquired(t *testing.T) {
|
||||||
constructor, _ := createConstructor()
|
constructor, _ := createConstructor()
|
||||||
pool := puddle.NewPool(constructor, stubDestructor, 10)
|
pool, err := puddle.NewPool(&puddle.Config[int]{Constructor: constructor, Destructor: stubDestructor, MaxSize: 10})
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
res, err := pool.Acquire(context.Background())
|
res, err := pool.Acquire(context.Background())
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
@@ -774,7 +808,8 @@ func TestResourcePanicsOnUsageWhenNotAcquired(t *testing.T) {
|
|||||||
|
|
||||||
func TestPoolAcquireReturnsErrorWhenPoolIsClosed(t *testing.T) {
|
func TestPoolAcquireReturnsErrorWhenPoolIsClosed(t *testing.T) {
|
||||||
constructor, _ := createConstructor()
|
constructor, _ := createConstructor()
|
||||||
pool := puddle.NewPool(constructor, stubDestructor, 10)
|
pool, err := puddle.NewPool(&puddle.Config[int]{Constructor: constructor, Destructor: stubDestructor, MaxSize: 10})
|
||||||
|
require.NoError(t, err)
|
||||||
pool.Close()
|
pool.Close()
|
||||||
|
|
||||||
res, err := pool.Acquire(context.Background())
|
res, err := pool.Acquire(context.Background())
|
||||||
@@ -792,7 +827,8 @@ func TestSignalIsSentWhenResourceFailedToCreate(t *testing.T) {
|
|||||||
}
|
}
|
||||||
destructor := func(value interface{}) {}
|
destructor := func(value interface{}) {}
|
||||||
|
|
||||||
pool := puddle.NewPool(constructor, destructor, 1)
|
pool, err := puddle.NewPool(&puddle.Config[any]{Constructor: constructor, Destructor: destructor, MaxSize: 10})
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
res1, err := pool.Acquire(context.Background())
|
res1, err := pool.Acquire(context.Background())
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
@@ -824,7 +860,8 @@ func TestStress(t *testing.T) {
|
|||||||
poolSize = 4
|
poolSize = 4
|
||||||
}
|
}
|
||||||
|
|
||||||
pool := puddle.NewPool(constructor, destructor, int32(poolSize))
|
pool, err := puddle.NewPool(&puddle.Config[int]{Constructor: constructor, Destructor: destructor, MaxSize: int32(poolSize)})
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
finishChan := make(chan struct{})
|
finishChan := make(chan struct{})
|
||||||
wg := &sync.WaitGroup{}
|
wg := &sync.WaitGroup{}
|
||||||
@@ -960,7 +997,10 @@ func ExamplePool() {
|
|||||||
}
|
}
|
||||||
maxPoolSize := int32(10)
|
maxPoolSize := int32(10)
|
||||||
|
|
||||||
pool := puddle.NewPool(constructor, destructor, maxPoolSize)
|
pool, err := puddle.NewPool(&puddle.Config[any]{Constructor: constructor, Destructor: destructor, MaxSize: int32(maxPoolSize)})
|
||||||
|
if err != nil {
|
||||||
|
log.Fatalln("NewPool", err)
|
||||||
|
}
|
||||||
|
|
||||||
// Use pool multiple times
|
// Use pool multiple times
|
||||||
for i := 0; i < 10; i++ {
|
for i := 0; i < 10; i++ {
|
||||||
@@ -1059,7 +1099,10 @@ func BenchmarkPoolAcquireAndRelease(b *testing.B) {
|
|||||||
wg := &sync.WaitGroup{}
|
wg := &sync.WaitGroup{}
|
||||||
|
|
||||||
constructor, _ := createConstructor()
|
constructor, _ := createConstructor()
|
||||||
pool := puddle.NewPool(constructor, stubDestructor, bm.poolSize)
|
pool, err := puddle.NewPool(&puddle.Config[int]{Constructor: constructor, Destructor: stubDestructor, MaxSize: bm.poolSize})
|
||||||
|
if err != nil {
|
||||||
|
b.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
for i := 0; i < bm.clientCount; i++ {
|
for i := 0; i < bm.clientCount; i++ {
|
||||||
wg.Add(1)
|
wg.Add(1)
|
||||||
|
|||||||
Reference in New Issue
Block a user