deadlock!
Phuong39 opened this issue · comments
Phuong39 commented
i tried Pool_WithCancelOnError but got deadlock , how fix it?
, thank
package main
import (
"context"
"errors"
"fmt"
"github.com/sourcegraph/conc/pool"
)
func main() {
ExampleContextPool_WithCancelOnError()
}
func ExampleContextPool_WithCancelOnError() {
p := pool.New().
WithMaxGoroutines(10).
WithContext(context.Background()).
WithCancelOnError()
for i := 0; i < 90; i++ {
i := i
p.Go(func(ctx context.Context) error {
if i == 10 {
return errors.New("I will cancel all other tasks!")
}
<-ctx.Done()
return nil
})
}
err := p.Wait()
fmt.Println(err)
// Output:
// I will cancel all other tasks!
}
fatal error: all goroutines are asleep - deadlock!
goroutine 1 [select]:
github.com/sourcegraph/conc/pool.(*Pool).Go(0xc000116600, 0xc0000ac5e8)
D:/gopath/src/github.com/sourcegraph/conc/pool/pool.go:54 +0x95
github.com/sourcegraph/conc/pool.(*ErrorPool).Go(0xc000116600, 0xc0000ac5d0)
D:/gopath/src/github.com/sourcegraph/conc/pool/error_pool.go:29 +0x7a
github.com/sourcegraph/conc/pool.(*ContextPool).Go(0xc000116600, 0xc0000af250)
D:/gopath/src/github.com/sourcegraph/conc/pool/context_pool.go:25 +0x7a
main.ExampleContextPool_WithCancelOnError()
/pool_t50.go:23 +0xc6
main.main()
/pool_t50.go:13 +0x17
goroutine 21 [chan receive]:
main.ExampleContextPool_WithCancelOnError.func1({0xa8ab90?, 0xc000092440?})
/pool_t50.go:27 +0x69
github.com/sourcegraph/conc/pool.(*ContextPool).Go.func1()
D:/gopath/src/github.com/sourcegraph/conc/pool/context_pool.go:26 +0x2e
github.com/sourcegraph/conc/pool.(*ErrorPool).Go.func1()
D:/gopath/src/github.com/sourcegraph/conc/pool/error_pool.go:30 +0x29
github.com/sourcegraph/conc/pool.(*Pool).worker(0x0?)
D:/gopath/src/github.com/sourcegraph/conc/pool/pool.go:154 +0x7a
github.com/sourcegraph/conc/panics.(*Catcher).Try(0x0?, 0x0?)
D:/gopath/src/github.com/sourcegraph/conc/panics/panics.go:23 +0x53
github.com/sourcegraph/conc.(*WaitGroup).Go.func1()
D:/gopath/src/github.com/sourcegraph/conc/waitgroup.go:32 +0x65
created by github.com/sourcegraph/conc.(*WaitGroup).Go
D:/gopath/src/github.com/sourcegraph/conc/waitgroup.go:30 +0x85
D:/gopath/src/github.com/sourcegraph/conc/waitgroup.go:32 +0x65
created by github.com/sourcegraph/conc.(*WaitGroup).Go
D:/gopath/src/github.com/sourcegraph/conc/waitgroup.go:30 +0x85
Saman Yousefisohi commented
This is not really an issue with this package firstly the context you have passed to your Pool
is using a context.Background()
which will never be "Done" (never sends anything to done channel).
Secondly you should use select to mitigate this issue.
package main
import (
"context"
"errors"
"fmt"
"github.com/sourcegraph/conc/pool"
)
func main() {
ExampleContextPool_WithCancelOnError()
}
func ExampleContextPool_WithCancelOnError() {
p := pool.New().
WithMaxGoroutines(10).
WithContext(context.Background()).
WithCancelOnError()
for i := 0; i < 90; i++ {
i := i
p.Go(func(ctx context.Context) error {
if i == 10 {
return errors.New("I will cancel all other tasks!")
}
select {
case <-ctx.Done():
return nil
default:
return nil
}
})
}
err := p.Wait()
fmt.Println(err)
// Output:
// I will cancel all other tasks!
}
Phuong39 commented
thanks,bro