本文主要研究一下gost的GoUnterminated
gost/runtime/goroutine.go
// GoUnterminated is used for which goroutine wanna long live as its process. // @period: sleep time duration after panic to defeat @handle panic so frequently. if it is not positive, // the @handle will be invoked asap after panic. func GoUnterminated(handle func(), wg *sync.WaitGroup, ignoreRecover bool, period time.Duration) { GoSafely(wg, ignoreRecover, handle, func(r interface{}) { if period > 0 { time.Sleep(period) } GoUnterminated(handle, wg, ignoreRecover, period) }, ) }
GoUnterminated方法提供handle、WaitGroup、ignoreRecover、period参数,其内部使用的是GoSafely,只是catchFunc是内置的;catchFunc对于period大于0的会sleep一下,之后还是执行GoUnterminated,这样子在handle出错(panic
)的时候会一直递归循环下去
gost/runtime/goroutine_test.go
func TestGoUnterminated(t *testing.T) { times := uint64(1) var wg sync.WaitGroup GoUnterminated( func() { if atomic.AddUint64(×, 1) == 2 { panic("hello") } }, &wg, false, 1e8, ) wg.Wait() assert.True(t, atomic.LoadUint64(×) == 3) GoUnterminated(func() { atomic.AddUint64(×, 1) }, nil, false, 1e8, ) time.Sleep(1e9) assert.True(t, atomic.LoadUint64(×) == 4) }
这里模拟了一下handler在times为1的时候产生panic,以及handler不产生panic就立刻结束的场景
gost提供了GoSafely方法,该方法提供handle、WaitGroup、ignoreRecover、period参数,其内部使用的是GoSafely,只是catchFunc是内置的;catchFunc对于period大于0的会sleep一下,之后还是执行GoUnterminated,这样子在handle出错(panic
)的时候会一直递归循环下去。