-
Couldn't load subscription status.
- Fork 151
Description
Seeing
blocked in BorrowObject
Environment
GO VERSION: 1.13
ARCH="amd64"
HOST="darwin"
Code
package main
import (
"context"
"fmt"
"strconv"
"sync/atomic"
"time"
pool "github.com/jolestar/go-commons-pool"
)
func main() {
type myPoolObject struct {
s string
}
v := uint64(0)
factory := pool.NewPooledObjectFactorySimple(
func(context.Context) (interface{}, error) {
return &myPoolObject{
s: strconv.FormatUint(atomic.AddUint64(&v, 1), 10),
},
nil
})
ctx := context.Background()
pc := pool.NewDefaultPoolConfig()
pc.MinIdle = 1
pc.MaxIdle = 1
pc.MaxTotal = 1
pc.MinEvictableIdleTime = time.Duration(1) * time.Minute
p := pool.NewObjectPool(context.Background(), factory, pc)
// to avoid this error: all goroutines are asleep - deadlock!
go func() {
for {
i := 100
i = i + 1
}
}()
for {
obj, err := p.BorrowObject(ctx)
if err != nil {
panic(err)
}
go func(obj interface{}) {
o := obj.(*myPoolObject)
fmt.Println(time.Now(), " result: ", o.s)
err = p.ReturnObject(ctx, obj)
if err != nil {
panic(err)
}
}(obj)
}
}Log
2019-11-08 09:57:24.5975 +0800 CST m=+0.749429025 result: 1
2019-11-08 09:57:24.597515 +0800 CST m=+0.749444445 result: 1
2019-11-08 09:57:24.59753 +0800 CST m=+0.749459549 result: 1
2019-11-08 09:57:24.597543 +0800 CST m=+0.749471943 result: 1
2019-11-08 09:57:24.597556 +0800 CST m=+0.749485330 result: 1
2019-11-08 09:57:24.597572 +0800 CST m=+0.749500902 result: 1
2019-11-08 09:57:24.597587 +0800 CST m=+0.749515746 result: 1
2019-11-08 09:57:24.597608 +0800 CST m=+0.749537522 result: 1
2019-11-08 09:57:24.597629 +0800 CST m=+0.749558045 result: 1
2019-11-08 09:57:24.597639 +0800 CST m=+0.749568376 result: 1
2019-11-08 09:57:24.597652 +0800 CST m=+0.749580667 result: 1
2019-11-08 09:57:24.597664 +0800 CST m=+0.749592752 result: 1
2019-11-08 09:57:24.597676 +0800 CST m=+0.749604811 result: 1
2019-11-08 09:57:24.597688 +0800 CST m=+0.749617130 result: 1
2019-11-08 09:57:24.5977 +0800 CST m=+0.749629502 result: 1
2019-11-08 09:57:24.597713 +0800 CST m=+0.749641599 result: 1
2019-11-08 09:57:24.597724 +0800 CST m=+0.749653596 result: 1
2019-11-08 09:57:24.597736 +0800 CST m=+0.749665538 result: 1
2019-11-08 09:57:24.597748 +0800 CST m=+0.749677438 result: 1
2019-11-08 09:57:24.597761 +0800 CST m=+0.749689620 result: 1
2019-11-08 09:57:24.597773 +0800 CST m=+0.749701772 result: 1
2019-11-08 09:57:24.597785 +0800 CST m=+0.749713650 result: 1
2019-11-08 09:57:24.597797 +0800 CST m=+0.749725604 result: 1
2019-11-08 09:57:24.597809 +0800 CST m=+0.749737630 result: 1
2019-11-08 09:57:24.597821 +0800 CST m=+0.749749838 result: 1
2019-11-08 09:57:24.597834 +0800 CST m=+0.749763114 result: 1
2019-11-08 09:57:24.597848 +0800 CST m=+0.749777219 result: 1
2019-11-08 09:57:24.597861 +0800 CST m=+0.749789852 result: 1
2019-11-08 09:57:24.598505 +0800 CST m=+0.750434037 result: 1
2019-11-08 09:57:24.598522 +0800 CST m=+0.750451430 result: 1
2019-11-08 09:57:24.598539 +0800 CST m=+0.750467751 result: 1
# blocked in BorrowObjectQuestions
Hi, I am using go-commons-pool as the implementation of thread pools in my project.
The codes upper show how I am using it. But you can find the program blocked in func BorrowObject.
Then I debugged the source code. The trace is:
ReturnObject --> AddFirst --> linkFirst --> q.notEmpty.Signal() --> case cond.signal <- 1:
If cond.signal is not writable which is caused by that nobody is waiting on this unbuffered channel to read, this signal will be dropped.
Right after that, BorrowObject wait on q.notEmpty and nobody will signal it because of dropped signals under the config pc.MaxTotal = 1 . The trace is:
borrowObject --> PollFirstWithContext --> interrupt = q.notEmpty.Wait(ctx) -- > case _, ok := <-ch:
Is the way I am using is wrong or indeed the bug it is?