package lifecycle import ( "context" "fmt" "github.com/gogf/gf/v2/frame/g" ) type BatchExecutor interface { Execute(ctx context.Context, batchNo string) error MarkFailed(ctx context.Context, batchNo, reason string) error } func Dispatch(executor BatchExecutor, batchNo string) { go func() { ctx := context.Background() defer func() { if recovered := recover(); recovered != nil { reason := fmt.Sprintf("后台执行异常: %v", recovered) g.Log().Errorf(ctx, "SIM lifecycle batch panic, batchNo=%s, reason=%s", batchNo, reason) if err := executor.MarkFailed(ctx, batchNo, reason); err != nil { g.Log().Errorf(ctx, "mark SIM lifecycle batch failed after panic, batchNo=%s, error=%+v", batchNo, err) } } }() if err := executor.Execute(ctx, batchNo); err != nil { g.Log().Errorf(ctx, "execute SIM lifecycle batch failed, batchNo=%s, error=%+v", batchNo, err) if markErr := executor.MarkFailed(ctx, batchNo, err.Error()); markErr != nil { g.Log().Errorf(ctx, "mark SIM lifecycle batch failed, batchNo=%s, error=%+v", batchNo, markErr) } } }() }