83 lines
2.7 KiB
Go
83 lines
2.7 KiB
Go
package task
|
||
|
||
import (
|
||
"context"
|
||
|
||
"git.huangwc.com/pig/pig-farm-controller/internal/infra/logs"
|
||
"git.huangwc.com/pig/pig-farm-controller/internal/infra/models"
|
||
"git.huangwc.com/pig/pig-farm-controller/internal/infra/repository"
|
||
"git.huangwc.com/pig/pig-farm-controller/internal/infra/utils"
|
||
)
|
||
|
||
// AnalysisPlanTaskManager 封装了创建和更新计划分析任务(即触发器)的逻辑。
|
||
// 这是一个可被 Scheduler 和其他应用服务(如 PlanService)共享的无状态组件。
|
||
type AnalysisPlanTaskManager struct {
|
||
planRepo repository.PlanRepository
|
||
pendingTaskRepo repository.PendingTaskRepository
|
||
executionLogRepo repository.ExecutionLogRepository
|
||
logger *logs.Logger
|
||
}
|
||
|
||
// NewAnalysisPlanTaskManager 是 AnalysisPlanTaskManager 的构造函数。
|
||
func NewAnalysisPlanTaskManager(
|
||
planRepo repository.PlanRepository,
|
||
pendingTaskRepo repository.PendingTaskRepository,
|
||
executionLogRepo repository.ExecutionLogRepository,
|
||
logger *logs.Logger,
|
||
) *AnalysisPlanTaskManager {
|
||
return &AnalysisPlanTaskManager{
|
||
planRepo: planRepo,
|
||
pendingTaskRepo: pendingTaskRepo,
|
||
executionLogRepo: executionLogRepo,
|
||
logger: logger,
|
||
}
|
||
}
|
||
|
||
// CreateOrUpdateTrigger 为给定的 planID 创建或更新其关联的下一次触发任务。
|
||
// 这个方法是幂等的,可以安全地被多次调用。
|
||
func (m *AnalysisPlanTaskManager) CreateOrUpdateTrigger(ctx context.Context, planID uint) error {
|
||
// 获取计划信息
|
||
plan, err := m.planRepo.GetBasicPlanByID(planID)
|
||
if err != nil {
|
||
m.logger.Errorf("[严重] 获取计划失败, 错误: %v", err)
|
||
return err
|
||
}
|
||
|
||
// 获取触发任务
|
||
task, err := m.planRepo.FindPlanAnalysisTaskByParamsPlanID(planID)
|
||
if err != nil {
|
||
m.logger.Errorf("[严重] 获取计划解析任务失败, 错误: %v", err)
|
||
return err
|
||
}
|
||
|
||
// 写入执行日志
|
||
taskLog := &models.TaskExecutionLog{
|
||
TaskID: task.ID,
|
||
Status: models.ExecutionStatusWaiting,
|
||
}
|
||
if err := m.executionLogRepo.CreateTaskExecutionLogsInBatch([]*models.TaskExecutionLog{taskLog}); err != nil {
|
||
m.logger.Errorf("[严重] 创建任务执行日志失败, 错误: %v", err)
|
||
return err
|
||
}
|
||
|
||
// 写入待执行队列
|
||
next, err := utils.GetNextCronTime(plan.CronExpression)
|
||
if err != nil {
|
||
m.logger.Errorf("[严重] 执行时间解析失败, 错误: %v", err)
|
||
return err
|
||
}
|
||
pendingTask := &models.PendingTask{
|
||
TaskID: task.ID,
|
||
ExecuteAt: next,
|
||
TaskExecutionLogID: taskLog.ID,
|
||
}
|
||
err = m.pendingTaskRepo.CreatePendingTasksInBatch([]*models.PendingTask{pendingTask})
|
||
if err != nil {
|
||
m.logger.Errorf("[严重] 创建待执行任务失败, 错误: %v", err)
|
||
return err
|
||
}
|
||
|
||
m.logger.Infof("成功为 Plan %d 创建/更新了下一次的触发任务,执行时间: %v", planID, next)
|
||
return nil
|
||
}
|