59 lines
1.3 KiB
Go
59 lines
1.3 KiB
Go
package utility
|
||
|
||
import (
|
||
"fmt"
|
||
"runtime"
|
||
"runtime/debug"
|
||
"strings"
|
||
"time"
|
||
|
||
"github.com/go-admin-team/go-admin-core/logger"
|
||
)
|
||
|
||
// SafeGo 安全地启动一个 goroutine,捕获 panic
|
||
func SafeGo(fn func()) {
|
||
go func() {
|
||
defer func() {
|
||
if r := recover(); r != nil {
|
||
// 记录 Goroutine ID、panic 信息和堆栈
|
||
logger.Error(fmt.Sprintf("Recovered from panic in Goroutine %s: %v\nStack Trace:\n%s", GetGoroutineID(), r, string(debug.Stack())))
|
||
}
|
||
}()
|
||
fn()
|
||
}()
|
||
}
|
||
|
||
// 获取 Goroutine ID
|
||
func GetGoroutineID() string {
|
||
buf := make([]byte, 64)
|
||
n := runtime.Stack(buf, false)
|
||
stack := string(buf[:n])
|
||
// 提取 Goroutine ID
|
||
id := strings.Split(stack, " ")[1]
|
||
return id
|
||
}
|
||
|
||
func SafeGoParam[T any](fn func(T), param T) {
|
||
go func() {
|
||
defer func() {
|
||
if r := recover(); r != nil {
|
||
logger.Error(fmt.Sprintf(" SafeGoParam Recovered from panic in Goroutine %s: %v\nStack Trace:\n%s", GetGoroutineID(), r, string(debug.Stack())))
|
||
}
|
||
}()
|
||
fn(param) // 执行传入的函数
|
||
}()
|
||
}
|
||
|
||
// Retry 重试执行函数,直到成功或达到最大重试次数
|
||
func Retry(max int, delay time.Duration, fn func() error) error {
|
||
var err error
|
||
for i := 0; i < max; i++ {
|
||
err = fn()
|
||
if err == nil {
|
||
return nil
|
||
}
|
||
time.Sleep(delay * time.Duration(i+1))
|
||
}
|
||
return err
|
||
}
|