diff --git a/os/grpool/grpool.go b/os/grpool/grpool.go index b1426fc77..48af508ef 100644 --- a/os/grpool/grpool.go +++ b/os/grpool/grpool.go @@ -9,6 +9,7 @@ package grpool import ( "errors" + "fmt" "github.com/gogf/gf/container/glist" "github.com/gogf/gf/container/gtype" @@ -47,6 +48,14 @@ func Add(f func()) error { return pool.Add(f) } +// AddWithRecover pushes a new job to the pool with specified recover function. +// The optional is called when any panic during executing of . +// If is not passed or given nil, it ignores the panic from . +// The job will be executed asynchronously. +func AddWithRecover(userFunc func(), recoverFunc ...func(err error)) error { + return pool.AddWithRecover(userFunc, recoverFunc...) +} + // Size returns current goroutine count of default goroutine pool. func Size() int { return pool.Size() @@ -81,6 +90,23 @@ func (p *Pool) Add(f func()) error { return nil } +// AddWithRecover pushes a new job to the pool with specified recover function. +// The optional is called when any panic during executing of . +// If is not passed or given nil, it ignores the panic from . +// The job will be executed asynchronously. +func (p *Pool) AddWithRecover(userFunc func(), recoverFunc ...func(err error)) error { + return p.Add(func() { + defer func() { + if err := recover(); err != nil { + if len(recoverFunc) > 0 && recoverFunc[0] != nil { + recoverFunc[0](errors.New(fmt.Sprintf(`%v`, err))) + } + } + }() + userFunc() + }) +} + // Cap returns the capacity of the pool. // This capacity is defined when pool is created. // It returns -1 if there's no limit. diff --git a/os/grpool/grpool_unit_test.go b/os/grpool/grpool_unit_test.go index 5aa9bd657..e0be156fe 100644 --- a/os/grpool/grpool_unit_test.go +++ b/os/grpool/grpool_unit_test.go @@ -97,6 +97,23 @@ func Test_Limit3(t *testing.T) { t.Assert(array.Len(), 100) t.Assert(pool.IsClosed(), true) t.AssertNE(pool.Add(func() {}), nil) - + }) +} + +func Test_AddWithRecover(t *testing.T) { + gtest.C(t, func(t *gtest.T) { + array := garray.NewArray(true) + grpool.AddWithRecover(func() { + array.Append(1) + panic(1) + }, func(err error) { + array.Append(1) + }) + grpool.AddWithRecover(func() { + panic(1) + array.Append(1) + }) + time.Sleep(500 * time.Millisecond) + t.Assert(array.Len(), 2) }) }