Smail/backend/utils/async/async.go
smail f60d3b0880
Some checks are pending
Security Checks / security (push) Waiting to run
整理前后端与测试构建目录并完善配置和安全引导
统一 frontend、backend、test、test-log 和 out 目录,更新构建、部署及测试入口;纳入配置管理兼容与首次安全引导修复;排除本机配置、密钥和测试产物。
2026-09-05 19:19:52 +08:00

72 lines
1.2 KiB
Go

package async
import (
"errors"
"git.pcux.cn/xuans/Smail/utils/context"
log "github.com/sirupsen/logrus"
"github.com/spf13/cast"
"runtime/debug"
"sync"
)
type Callback func(params any)
type Async struct {
wg *sync.WaitGroup
lastError error
ctx *context.Context
}
func New(ctx *context.Context) *Async {
return &Async{
ctx: ctx,
}
}
func (as *Async) LastError() error {
return as.lastError
}
func (as *Async) WaitProcess(callback Callback, params any) {
if as.wg == nil {
as.wg = &sync.WaitGroup{}
}
as.wg.Add(1)
as.Process(func(params any) {
defer as.wg.Done()
callback(params)
}, params)
}
func (as *Async) Process(callback Callback, params any) {
go func() {
defer func() {
if err := recover(); err != nil {
as.lastError = as.HandleErrRecover(err)
}
}()
callback(params)
}()
}
func (as *Async) Wait() {
if as.wg == nil {
return
}
as.wg.Wait()
}
// HandleErrRecover panic恢复处理
func (as *Async) HandleErrRecover(err interface{}) (returnErr error) {
switch err.(type) {
case error:
returnErr = err.(error)
default:
returnErr = errors.New(cast.ToString(err))
}
log.WithContext(as.ctx).Errorf("goroutine panic:%s \n %s", err, string(debug.Stack()))
return
}