Add banchmarks with cancelled acquires
This commit is contained in:
committed by
Jack Christensen
parent
47b52af713
commit
4fbc609092
@@ -0,0 +1,7 @@
|
|||||||
|
package puddle
|
||||||
|
|
||||||
|
import "context"
|
||||||
|
|
||||||
|
func (p *Pool[T]) AcquireRaw(ctx context.Context) (*Resource[T], error) {
|
||||||
|
return p.acquire(ctx)
|
||||||
|
}
|
||||||
@@ -293,7 +293,6 @@ func (ctx *valueCancelCtx) Value(key any) any { return ctx.valueCtx.Va
|
|||||||
// the problem of it being impossible to create resources when the time to create a resource is greater than any one
|
// the problem of it being impossible to create resources when the time to create a resource is greater than any one
|
||||||
// caller of Acquire is willing to wait.
|
// caller of Acquire is willing to wait.
|
||||||
func (p *Pool[T]) Acquire(ctx context.Context) (*Resource[T], error) {
|
func (p *Pool[T]) Acquire(ctx context.Context) (*Resource[T], error) {
|
||||||
startNano := nanotime()
|
|
||||||
if doneChan := ctx.Done(); doneChan != nil {
|
if doneChan := ctx.Done(); doneChan != nil {
|
||||||
select {
|
select {
|
||||||
case <-ctx.Done():
|
case <-ctx.Done():
|
||||||
@@ -305,6 +304,13 @@ func (p *Pool[T]) Acquire(ctx context.Context) (*Resource[T], error) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return p.acquire(ctx)
|
||||||
|
}
|
||||||
|
|
||||||
|
// acquire is a continuation of Acquire function that doesn't check context
|
||||||
|
// validity. This function exists separatly only for benchmarking purposes.
|
||||||
|
func (p *Pool[T]) acquire(ctx context.Context) (*Resource[T], error) {
|
||||||
|
startNano := nanotime()
|
||||||
p.cond.L.Lock()
|
p.cond.L.Lock()
|
||||||
|
|
||||||
emptyAcquire := false
|
emptyAcquire := false
|
||||||
|
|||||||
+78
-9
@@ -1226,26 +1226,33 @@ func BenchmarkAcquire_ReleaseAfterAcquire(b *testing.B) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func BenchmarkAcquire_ReleaseAfterAcquireWithCPUOverload(b *testing.B) {
|
func withCPULoad() {
|
||||||
r := require.New(b)
|
|
||||||
ctx := context.Background()
|
|
||||||
pool := benchmarkPool[int32](b)
|
|
||||||
releaseChan := releaser[int32](b)
|
|
||||||
|
|
||||||
// Multiply by 2 to similate overload of the system.
|
// Multiply by 2 to similate overload of the system.
|
||||||
numGoroutines := runtime.NumCPU() * 2
|
numGoroutines := runtime.NumCPU() * 2
|
||||||
|
|
||||||
|
var wg sync.WaitGroup
|
||||||
for i := 0; i < numGoroutines; i++ {
|
for i := 0; i < numGoroutines; i++ {
|
||||||
startChan := make(chan struct{})
|
wg.Add(1)
|
||||||
go func() {
|
go func() {
|
||||||
close(startChan)
|
wg.Done()
|
||||||
|
|
||||||
// Similate computationally intensive task.
|
// Similate computationally intensive task.
|
||||||
for j := 0; true; j++ {
|
for j := 0; true; j++ {
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
<-startChan
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
wg.Wait()
|
||||||
|
}
|
||||||
|
|
||||||
|
func BenchmarkAcquire_ReleaseAfterAcquireWithCPULoad(b *testing.B) {
|
||||||
|
r := require.New(b)
|
||||||
|
ctx := context.Background()
|
||||||
|
pool := benchmarkPool[int32](b)
|
||||||
|
releaseChan := releaser[int32](b)
|
||||||
|
|
||||||
|
withCPULoad()
|
||||||
|
|
||||||
res, err := pool.Acquire(ctx)
|
res, err := pool.Acquire(ctx)
|
||||||
r.NoError(err)
|
r.NoError(err)
|
||||||
// We need to release the last connection. Otherwise the pool.Close()
|
// We need to release the last connection. Otherwise the pool.Close()
|
||||||
@@ -1259,3 +1266,65 @@ func BenchmarkAcquire_ReleaseAfterAcquireWithCPUOverload(b *testing.B) {
|
|||||||
r.NoError(err)
|
r.NoError(err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func BenchmarkAcquire_MultipleCancelled(b *testing.B) {
|
||||||
|
const cancelCnt = 64
|
||||||
|
|
||||||
|
r := require.New(b)
|
||||||
|
ctx := context.Background()
|
||||||
|
pool := benchmarkPool[int32](b)
|
||||||
|
releaseChan := releaser[int32](b)
|
||||||
|
|
||||||
|
cancelCtx, cancel := context.WithCancel(ctx)
|
||||||
|
cancel()
|
||||||
|
|
||||||
|
res, err := pool.Acquire(ctx)
|
||||||
|
r.NoError(err)
|
||||||
|
// We need to release the last connection. Otherwise the pool.Close()
|
||||||
|
// method will block and this function will never return.
|
||||||
|
defer func() { res.Release() }()
|
||||||
|
|
||||||
|
b.ResetTimer()
|
||||||
|
for i := 0; i < b.N; i++ {
|
||||||
|
for j := 0; j < cancelCnt; j++ {
|
||||||
|
_, err = pool.AcquireRaw(cancelCtx)
|
||||||
|
r.Equal(context.Canceled, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
releaseChan <- res
|
||||||
|
res, err = pool.Acquire(ctx)
|
||||||
|
r.NoError(err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func BenchmarkAcquire_MultipleCancelledWithCPULoad(b *testing.B) {
|
||||||
|
const cancelCnt = 3
|
||||||
|
|
||||||
|
r := require.New(b)
|
||||||
|
ctx := context.Background()
|
||||||
|
pool := benchmarkPool[int32](b)
|
||||||
|
releaseChan := releaser[int32](b)
|
||||||
|
|
||||||
|
cancelCtx, cancel := context.WithCancel(ctx)
|
||||||
|
cancel()
|
||||||
|
|
||||||
|
withCPULoad()
|
||||||
|
|
||||||
|
res, err := pool.Acquire(ctx)
|
||||||
|
r.NoError(err)
|
||||||
|
// We need to release the last connection. Otherwise the pool.Close()
|
||||||
|
// method will block and this function will never return.
|
||||||
|
defer func() { res.Release() }()
|
||||||
|
|
||||||
|
b.ResetTimer()
|
||||||
|
for i := 0; i < b.N; i++ {
|
||||||
|
for j := 0; j < cancelCnt; j++ {
|
||||||
|
_, err = pool.AcquireRaw(cancelCtx)
|
||||||
|
r.Equal(context.Canceled, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
releaseChan <- res
|
||||||
|
res, err = pool.Acquire(ctx)
|
||||||
|
r.NoError(err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user