deadlock in BorrowObject
xhjmc opened this issue · 2 comments
xhjmc commented
Problem
When creating object fails and using n goroutines (n > MaxTotal) to call BorrowObject, it will deadlock. But when I lock BorrowObject, the deadlock will not happen. Is this a bug?
Env
go version 1.13
windows10
go-commons-pool version v2.11
Code
package pool
import (
"context"
"errors"
"fmt"
"github.com/jolestar/go-commons-pool/v2"
"sync"
"testing"
"time"
)
func TestPool(t *testing.T) {
factory := pool.NewPooledObjectFactorySimple(
func(context.Context) (interface{}, error) {
time.Sleep(time.Second)
return nil, errors.New("create object fail") // simulate the failure of creating objects
})
ctx := context.Background()
conf := pool.NewDefaultPoolConfig()
conf.MaxTotal = 1
p := pool.NewObjectPool(ctx, factory, conf)
n := 2
wg := sync.WaitGroup{}
wg.Add(n)
//lock := sync.Mutex{}
for i := 0; i < n; i++ {
id := i
go func() { // when using goroutines without locking BorrowObject, it will deadlock
defer wg.Done()
fmt.Println(id, "before borrow")
//lock.Lock()
obj, err := p.BorrowObject(ctx)
//lock.Unlock()
fmt.Println(id, "after borrow")
if err != nil {
fmt.Println(id, "borrow err:", err)
}
err = p.ReturnObject(ctx, obj)
if err != nil {
fmt.Println(id, "return err:", err)
}
}()
}
wg.Wait()
}
xhjmc commented
Env fix
go version 1.13.1
go-commons-pool version v2.1.1
jolestar commented
- the first goroutine is blocked by time.Sleep, and use the 1 MaxTotal limit object。
- the second goroutine can not create a new object, so just wait for a returned object at PollFirstWithContext, but not one to return object, so deadlocked.
Please set a timeout to ctx, or increment the MaxTotal config, this is not a bug.