2
0

Fix: Resource.Destroy removed self from pool after destructor complete

This commit is contained in:
Jack Christensen
2020-08-20 21:56:47 -05:00
parent 6706e16fc2
commit 6d0ef02e90
3 changed files with 15 additions and 6 deletions
+4
View File
@@ -1,3 +1,7 @@
# Unreleased
* Fix: Resource.Destroy no longer removes itself from the pool before its destructor has completed.
# 1.1.1 (April 2, 2020)
* Pool.Close can be safely called multiple times
+2 -4
View File
@@ -64,7 +64,7 @@ func (res *Resource) Destroy() {
if res.status != resourceStatusAcquired {
panic("tried to destroy resource that is not acquired")
}
res.pool.destroyAcquiredResource(res)
go res.pool.destroyAcquiredResource(res)
}
// Hijack assumes ownership of the resource from the pool. Caller is responsible
@@ -435,11 +435,9 @@ func (p *Pool) releaseAcquiredResource(res *Resource, lastUsedNano int64) {
// Remove removes res from the pool and closes it. If res is not part of the
// pool Remove will panic.
func (p *Pool) destroyAcquiredResource(res *Resource) {
p.destructResourceValue(res.value)
p.cond.L.Lock()
p.allResources = removeResource(p.allResources, res)
go p.destructResourceValue(res.value)
p.cond.L.Unlock()
p.cond.Signal()
}
+9 -2
View File
@@ -482,7 +482,7 @@ func TestPoolStatCanceledAcquireDuringWait(t *testing.T) {
assert.Equal(t, int64(1), stat.CanceledAcquireCount())
}
func TestResourceDestroyRemovesResourceFromPool(t *testing.T) {
func TestResourceHijackRemovesResourceFromPoolButDoesNotDestroy(t *testing.T) {
constructor, _ := createConstructor()
var destructorCalls Counter
destructor := func(interface{}) {
@@ -506,7 +506,7 @@ func TestResourceDestroyRemovesResourceFromPool(t *testing.T) {
res.IdleDuration()
}
func TestResourceHijackRemovesResourceFromPoolButDoesNotDestroy(t *testing.T) {
func TestResourceDestroyRemovesResourceFromPool(t *testing.T) {
constructor, _ := createConstructor()
pool := puddle.NewPool(constructor, stubDestructor, 10)
@@ -516,6 +516,13 @@ func TestResourceHijackRemovesResourceFromPoolButDoesNotDestroy(t *testing.T) {
assert.EqualValues(t, 1, pool.Stat().TotalResources())
res.Destroy()
for i := 0; i < 1000; i++ {
if pool.Stat().TotalResources() == 0 {
break
}
time.Sleep(time.Millisecond)
}
assert.EqualValues(t, 0, pool.Stat().TotalResources())
}