ai_scheduler/internal/pkg/util/safe_pool.go

63 lines
1.4 KiB
Go

package util
import (
"os"
"runtime/debug"
"sync"
"time"
"github.com/bytedance/gopkg/util/gopool"
"github.com/go-kratos/kratos/v2/log"
)
var (
logger *log.Helper
once sync.Once
)
// getLogger 懒加载获取日志器
func getLogger() *log.Helper {
once.Do(func() {
// 如果没有手动初始化,使用默认的标准输出日志器
if logger == nil {
stdLogger := log.With(log.NewStdLogger(os.Stdout),
"ts", log.DefaultTimestamp,
"caller", log.DefaultCaller,
"component", "safe_pool",
)
logger = log.NewHelper(stdLogger)
}
})
return logger
}
// InitSafePool 初始化安全协程池(可选,如果不调用会使用默认日志器)
func InitSafePool(l log.Logger) {
logger = log.NewHelper(l)
}
// SafeGo 安全执行协程
// taskName: 协程任务名称,用于日志记录
// fn: 要执行的函数
func SafeGo(taskName string, fn func()) {
gopool.Go(func() {
defer func() {
if r := recover(); r != nil {
stack := debug.Stack()
getLogger().Errorf("协程 [%s] 发生panic: %v\n堆栈信息:\n%s", taskName, r, string(stack))
}
}()
// 记录协程开始执行
getLogger().Infof("协程 [%s] 开始执行", taskName)
start := time.Now()
// 执行用户函数
fn()
// 记录协程执行完成
duration := time.Since(start)
getLogger().Infof("协程 [%s] 执行完成,耗时: %v", taskName, duration)
})
}