package common import ( "fmt" "runtime/debug" "sync" "sync/atomic" "time" "91porn-server/common/log" "91porn-server/common/stderr" ) var ( routinePanicHandler func(string) routineCount int64 ) func SetPanicHandler(handler func(string)) { routinePanicHandler = handler } func Go(f func()) { atomic.AddInt64(&routineCount, 1) go func() { defer func() { atomic.AddInt64(&routineCount, -1) if r := recover(); r != nil { log.Error("【Warning】serevr occour error,please attention", log.Any("Detail", r)) if routinePanicHandler != nil { var stack string if !stderr.IsContain(r, stderr.WriteBrokenError) { stack = string(debug.Stack()) } routinePanicHandler(fmt.Sprintf("[Panic] routineCount:%d \n err: %+v\n", routineCount, r) + stack) } } }() f() }() } func GoParam(i int, f func(i int)) { atomic.AddInt64(&routineCount, 1) go func(i int) { defer func() { atomic.AddInt64(&routineCount, -1) if r := recover(); r != nil { log.Error("【Warning】serevr occour error,please attention", log.Any("Detail", r)) if routinePanicHandler != nil { var stack string if !stderr.IsContain(r, stderr.WriteBrokenError) { stack = string(debug.Stack()) } routinePanicHandler(fmt.Sprintf("[Panic] routineCount:%d \n err: %+v\n", routineCount, r) + stack) } } }() f(i) }(i) } // WaitGoQuit 等待go退出,timeoutSec 超时秒数,<=0表示不超时 func WaitGoQuit(timeoutSec int32) { for { count := atomic.LoadInt64(&routineCount) if count == 0 { return } time.Sleep(time.Second) if timeoutSec > 0 { timeoutSec-- if timeoutSec == 0 { return } } } } func GoAndWait(funcs ...func() error) (err error) { var wg sync.WaitGroup wg.Add(len(funcs)) for i := range funcs { go func(f func() error) { atomic.AddInt64(&routineCount, 1) defer wg.Done() defer func() { atomic.AddInt64(&routineCount, -1) if r := recover(); r != nil { log.Error("【Warning】serevr occour error,please attention", log.Any("Detail", r)) if routinePanicHandler != nil { var stack string if !stderr.IsContain(r, stderr.WriteBrokenError) { stack = string(debug.Stack()) } routinePanicHandler(fmt.Sprintf("[Panic] routineCount:%d \n err: %+v\n", routineCount, r) + stack) } } }() if routineErr := f(); routineErr != nil { err = routineErr } }(funcs[i]) } wg.Wait() return }