Merge branch 'last-used-time' of git://github.com/ellulpatrick/puddle into ellulpatrick-last-used-time
This commit is contained in:
@@ -29,6 +29,7 @@ type Resource struct {
|
||||
value interface{}
|
||||
pool *Pool
|
||||
creationTime time.Time
|
||||
lastUsedTime time.Time
|
||||
status byte
|
||||
}
|
||||
|
||||
@@ -45,7 +46,16 @@ func (res *Resource) Release() {
|
||||
if res.status != resourceStatusAcquired {
|
||||
panic("tried to release resource that is not acquired")
|
||||
}
|
||||
res.pool.releaseAcquiredResource(res)
|
||||
res.pool.releaseAcquiredResource(res, true)
|
||||
}
|
||||
|
||||
// Release returns the resource to the pool after it was acquired via AcquireAllIdle.
|
||||
// It does not updates lastUsedTime. res must not be subsequently used.
|
||||
func (res *Resource) ReleaseIdle() {
|
||||
if res.status != resourceStatusAcquired {
|
||||
panic("tried to release resource that is not acquired")
|
||||
}
|
||||
res.pool.releaseAcquiredResource(res, false)
|
||||
}
|
||||
|
||||
// Destroy returns the resource to the pool for destruction. res must not be
|
||||
@@ -74,6 +84,15 @@ func (res *Resource) CreationTime() time.Time {
|
||||
return res.creationTime
|
||||
}
|
||||
|
||||
// LastUsedTime returns when the resource was last used, specifically when
|
||||
// it was released from a normal Acquire (not from an AcquireAllIdle)
|
||||
func (res *Resource) LastUsedTime() time.Time {
|
||||
if !(res.status == resourceStatusAcquired || res.status == resourceStatusHijacked) {
|
||||
panic("tried to access resource that is not acquired or hijacked")
|
||||
}
|
||||
return res.lastUsedTime
|
||||
}
|
||||
|
||||
// Pool is a concurrency-safe resource pool.
|
||||
type Pool struct {
|
||||
cond *sync.Cond
|
||||
@@ -339,10 +358,13 @@ func (p *Pool) AcquireAllIdle() []*Resource {
|
||||
}
|
||||
|
||||
// releaseAcquiredResource returns res to the the pool.
|
||||
func (p *Pool) releaseAcquiredResource(res *Resource) {
|
||||
func (p *Pool) releaseAcquiredResource(res *Resource, updateLastUsed bool) {
|
||||
p.cond.L.Lock()
|
||||
|
||||
if !p.closed {
|
||||
if updateLastUsed {
|
||||
res.lastUsedTime = time.Now()
|
||||
}
|
||||
res.status = resourceStatusIdle
|
||||
p.idleResources = append(p.idleResources, res)
|
||||
} else {
|
||||
|
||||
+16
-9
@@ -218,6 +218,8 @@ func TestPoolAcquireAllIdle(t *testing.T) {
|
||||
|
||||
resources[0], err = pool.Acquire(context.Background())
|
||||
require.NoError(t, err)
|
||||
assert.True(t, resources[0].LastUsedTime().IsZero(), "lastUsedTime should start as Zero")
|
||||
|
||||
resources[1], err = pool.Acquire(context.Background())
|
||||
require.NoError(t, err)
|
||||
resources[2], err = pool.Acquire(context.Background())
|
||||
@@ -226,23 +228,25 @@ func TestPoolAcquireAllIdle(t *testing.T) {
|
||||
require.NoError(t, err)
|
||||
|
||||
assert.Len(t, pool.AcquireAllIdle(), 0)
|
||||
|
||||
resources[0].Release()
|
||||
resources[3].Release()
|
||||
|
||||
assert.ElementsMatch(t, []*puddle.Resource{resources[0], resources[3]}, pool.AcquireAllIdle())
|
||||
r0LastUsedTime := resources[0].LastUsedTime()
|
||||
assert.WithinDuration(t, time.Now(), r0LastUsedTime, time.Second, "should have updated lastUsedTime")
|
||||
time.Sleep(1 * time.Millisecond) // sleep before releasing
|
||||
resources[0].ReleaseIdle()
|
||||
resources[3].ReleaseIdle()
|
||||
|
||||
resources[0].Release()
|
||||
resources[3].Release()
|
||||
resources[1].Release()
|
||||
resources[2].Release()
|
||||
|
||||
assert.ElementsMatch(t, resources, pool.AcquireAllIdle())
|
||||
|
||||
resources[0].Release()
|
||||
resources[1].Release()
|
||||
resources[2].Release()
|
||||
resources[3].Release()
|
||||
assert.Equal(t, r0LastUsedTime, resources[0].LastUsedTime(), "should not have updated lastUsedTime")
|
||||
resources[0].ReleaseIdle()
|
||||
resources[1].ReleaseIdle()
|
||||
resources[2].ReleaseIdle()
|
||||
resources[3].ReleaseIdle()
|
||||
}
|
||||
|
||||
func TestPoolCloseClosesAllIdleResources(t *testing.T) {
|
||||
@@ -465,9 +469,10 @@ func TestResourceDestroyRemovesResourceFromPool(t *testing.T) {
|
||||
assert.EqualValues(t, 0, pool.Stat().TotalResources())
|
||||
assert.EqualValues(t, 0, destructorCalls.Value())
|
||||
|
||||
// Can still call Value and CreationTime
|
||||
// Can still call Value, CreationTime and LastUsedTime
|
||||
res.Value()
|
||||
res.CreationTime()
|
||||
res.LastUsedTime()
|
||||
}
|
||||
|
||||
func TestResourceHijackRemovesResourceFromPoolButDoesNotDestroy(t *testing.T) {
|
||||
@@ -492,10 +497,12 @@ func TestResourcePanicsOnUsageWhenNotAcquired(t *testing.T) {
|
||||
res.Release()
|
||||
|
||||
assert.PanicsWithValue(t, "tried to release resource that is not acquired", res.Release)
|
||||
assert.PanicsWithValue(t, "tried to release resource that is not acquired", res.ReleaseIdle)
|
||||
assert.PanicsWithValue(t, "tried to destroy resource that is not acquired", res.Destroy)
|
||||
assert.PanicsWithValue(t, "tried to hijack resource that is not acquired", res.Hijack)
|
||||
assert.PanicsWithValue(t, "tried to access resource that is not acquired or hijacked", func() { res.Value() })
|
||||
assert.PanicsWithValue(t, "tried to access resource that is not acquired or hijacked", func() { res.CreationTime() })
|
||||
assert.PanicsWithValue(t, "tried to access resource that is not acquired or hijacked", func() { res.LastUsedTime() })
|
||||
}
|
||||
|
||||
func TestPoolAcquireReturnsErrorWhenPoolIsClosed(t *testing.T) {
|
||||
|
||||
Reference in New Issue
Block a user