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
 | ||
| }
 |