2
0

Ensure that conditional variable is signaled if resource failed to create

This commit is contained in:
Evgeny Vanslov
2020-12-03 19:14:39 +00:00
parent 8a2237ffa5
commit 513cb84ff5
2 changed files with 32 additions and 0 deletions
+1
View File
@@ -316,6 +316,7 @@ func (p *Pool) Acquire(ctx context.Context) (*Resource, error) {
}
p.cond.L.Unlock()
p.cond.Signal()
return nil, err
}
+31
View File
@@ -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