fix: 完成商务迁移复核与接口优化并清理历史资料
This commit is contained in:
@@ -211,7 +211,34 @@ func (e *TaskExecutor) runMethod(ctx context.Context, task *taskbiz.TimedTask) e
|
||||
if e.methodOrphaned(task.ID) {
|
||||
return errTaskOrphaned
|
||||
}
|
||||
runCtx, cancel := context.WithTimeout(ctx, 5*time.Minute)
|
||||
options, err := taskbiz.MethodExecutionOptions(task.Params)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
for attempt := 0; attempt <= options.MaxRetryTimes; attempt++ {
|
||||
err = e.runMethodAttempt(ctx, task, method, options.Timeout)
|
||||
if err == nil || ctx.Err() != nil || errors.Is(err, context.Canceled) || e.methodOrphaned(task.ID) {
|
||||
return err
|
||||
}
|
||||
if attempt < options.MaxRetryTimes {
|
||||
slog.WarnContext(ctx, "任务执行失败,准备重试", "task_id", task.ID, "method", task.MethodName, "attempt", attempt+1, "max_retry_times", options.MaxRetryTimes, "error", err)
|
||||
timer := time.NewTimer(options.RetryInterval)
|
||||
select {
|
||||
case <-ctx.Done():
|
||||
timer.Stop()
|
||||
if errors.Is(ctx.Err(), context.DeadlineExceeded) {
|
||||
return errTaskTimeout
|
||||
}
|
||||
return ctx.Err()
|
||||
case <-timer.C:
|
||||
}
|
||||
}
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
func (e *TaskExecutor) runMethodAttempt(ctx context.Context, task *taskbiz.TimedTask, method platformtask.MethodFunc, timeout time.Duration) error {
|
||||
runCtx, cancel := context.WithTimeout(ctx, timeout)
|
||||
defer cancel()
|
||||
done := make(chan error, 1)
|
||||
go func() {
|
||||
@@ -224,9 +251,12 @@ func (e *TaskExecutor) runMethod(ctx context.Context, task *taskbiz.TimedTask) e
|
||||
}()
|
||||
select {
|
||||
case err := <-done:
|
||||
if errors.Is(err, context.DeadlineExceeded) {
|
||||
if errors.Is(err, context.DeadlineExceeded) || errors.Is(runCtx.Err(), context.DeadlineExceeded) {
|
||||
return errTaskTimeout
|
||||
}
|
||||
if runCtx.Err() != nil {
|
||||
return runCtx.Err()
|
||||
}
|
||||
return err
|
||||
case <-runCtx.Done():
|
||||
e.markMethodOrphan(task.ID, done)
|
||||
|
||||
@@ -52,6 +52,49 @@ func TestRunMethodConvertsPanicToError(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestRunMethodUsesImportedDeadlineAndRetries(t *testing.T) {
|
||||
registry := platformtask.NewRegistry()
|
||||
attempts := 0
|
||||
registry.Register(platformtask.Method{Name: "migrated-retry", Run: func(ctx context.Context, _ json.RawMessage) error {
|
||||
attempts++
|
||||
deadline, ok := ctx.Deadline()
|
||||
if !ok || time.Until(deadline) < 1590*time.Second || time.Until(deadline) > 1600*time.Second {
|
||||
return errors.New("迁移的 1600 秒超时未生效")
|
||||
}
|
||||
if attempts < 3 {
|
||||
return errors.New("temporary")
|
||||
}
|
||||
return nil
|
||||
}})
|
||||
executor := &TaskExecutor{methods: registry}
|
||||
task := &taskbiz.TimedTask{MethodName: "migrated-retry", Params: []byte(`{"_execution":{"timeoutSeconds":1600,"maxRetryTimes":3,"retryIntervalSeconds":0}}`)}
|
||||
if err := executor.runMethod(context.Background(), task); err != nil || attempts != 3 {
|
||||
t.Fatalf("迁移重试未生效: attempts=%d err=%v", attempts, err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestRunMethodCancellationStopsRetryDelay(t *testing.T) {
|
||||
registry := platformtask.NewRegistry()
|
||||
started := make(chan struct{})
|
||||
registry.Register(platformtask.Method{Name: "cancel-retry", Run: func(context.Context, json.RawMessage) error { close(started); return errors.New("temporary") }})
|
||||
executor := &TaskExecutor{methods: registry}
|
||||
ctx, cancel := context.WithCancel(context.Background())
|
||||
done := make(chan error, 1)
|
||||
go func() {
|
||||
done <- executor.runMethod(ctx, &taskbiz.TimedTask{MethodName: "cancel-retry", Params: []byte(`{"_execution":{"maxRetryTimes":3,"retryIntervalSeconds":60}}`)})
|
||||
}()
|
||||
<-started
|
||||
cancel()
|
||||
select {
|
||||
case err := <-done:
|
||||
if !errors.Is(err, context.Canceled) {
|
||||
t.Fatalf("取消重试错误: %v", err)
|
||||
}
|
||||
case <-time.After(time.Second):
|
||||
t.Fatal("重试等待没有响应取消")
|
||||
}
|
||||
}
|
||||
|
||||
func TestRunMethodUsesParentContext(t *testing.T) {
|
||||
const methodName = "worker-test-parent-context"
|
||||
started := make(chan struct{})
|
||||
|
||||
@@ -20,10 +20,11 @@ type TaskMethods struct {
|
||||
media *system.MediaUsecase
|
||||
runtime *config.Store
|
||||
reports *business.ReportBuildUsecase
|
||||
alerts *business.AlertTriggerUsecase
|
||||
}
|
||||
|
||||
func NewTaskMethods(tasks *taskbiz.TaskUsecase, maintenance *system.MaintenanceUsecase, media *system.MediaUsecase, runtime *config.Store, reports *business.ReportBuildUsecase) *TaskMethods {
|
||||
return &TaskMethods{tasks: tasks, maintenance: maintenance, media: media, runtime: runtime, reports: reports}
|
||||
func NewTaskMethods(tasks *taskbiz.TaskUsecase, maintenance *system.MaintenanceUsecase, media *system.MediaUsecase, runtime *config.Store, reports *business.ReportBuildUsecase, alerts *business.AlertTriggerUsecase) *TaskMethods {
|
||||
return &TaskMethods{tasks: tasks, maintenance: maintenance, media: media, runtime: runtime, reports: reports, alerts: alerts}
|
||||
}
|
||||
|
||||
func (methods *TaskMethods) RegisterTasks(registry *platformtask.Registry) {
|
||||
@@ -31,6 +32,15 @@ func (methods *TaskMethods) RegisterTasks(registry *platformtask.Registry) {
|
||||
return
|
||||
}
|
||||
methods.registerBusinessReports(registry)
|
||||
registry.Register(platformtask.Method{Name: "alertTriggerTask", Description: "按商务范围检测并生成预警", Run: func(ctx context.Context, _ json.RawMessage) error {
|
||||
if methods.alerts == nil {
|
||||
return errors.New("预警任务依赖未就绪")
|
||||
}
|
||||
if ctx == nil {
|
||||
ctx = context.Background()
|
||||
}
|
||||
return methods.alerts.Run(ctx)
|
||||
}})
|
||||
descriptions := map[string]string{}
|
||||
for _, task := range taskmodule.TimedTasks() {
|
||||
descriptions[task.MethodName] = task.Description
|
||||
|
||||
Reference in New Issue
Block a user