From 513cb84ff5d538f6d6f586a21a3d7f525f44e63d Mon Sep 17 00:00:00 2001 From: Evgeny Vanslov Date: Thu, 3 Dec 2020 19:14:39 +0000 Subject: [PATCH] Ensure that conditional variable is signaled if resource failed to create --- pool.go | 1 + pool_test.go | 31 +++++++++++++++++++++++++++++++ 2 files changed, 32 insertions(+) diff --git a/pool.go b/pool.go index 0d6d9ef..9123572 100644 --- a/pool.go +++ b/pool.go @@ -316,6 +316,7 @@ func (p *Pool) Acquire(ctx context.Context) (*Resource, error) { } p.cond.L.Unlock() + p.cond.Signal() return nil, err } diff --git a/pool_test.go b/pool_test.go index 074aa47..ae4aa82 100644 --- a/pool_test.go +++ b/pool_test.go @@ -9,6 +9,7 @@ import ( "net" "os" "runtime" + "strconv" "sync" "testing" "time" @@ -634,6 +635,36 @@ func TestPoolAcquireReturnsErrorWhenPoolIsClosed(t *testing.T) { assert.Nil(t, res) } +func TestSignalIsSentWhenResourceFailedToCreate(t *testing.T) { + var c Counter + constructor := func(context.Context) (a interface{}, err error) { + if c.Next() == 2 { + return nil, errors.New("outage") + } + return 1, nil + } + destructor := func(value interface{}) {} + + pool := puddle.NewPool(constructor, destructor, 1) + + res1, err := pool.Acquire(context.Background()) + require.NoError(t, err) + + var wg sync.WaitGroup + for i := 0; i < 2; i++ { + wg.Add(1) + go func(name string) { + defer wg.Done() + _, _ = pool.Acquire(context.Background()) + }(strconv.Itoa(i)) + } + + // ensure that both goroutines above are waiting for condition variable signal + time.Sleep(500 * time.Millisecond) + res1.Destroy() + wg.Wait() +} + func TestStress(t *testing.T) { constructor, _ := createConstructor() var destructorCalls Counter