1. 增加任务调度器配置文件

2. 创建/更新计划会自动处理触发器
This commit is contained in:
2025-09-17 23:01:15 +08:00
parent f7a5e4737d
commit 810049d62e
7 changed files with 90 additions and 42 deletions

View File

@@ -29,6 +29,9 @@ type Config struct {
// Heartbeat 心跳配置
Heartbeat HeartbeatConfig `yaml:"heartbeat"`
// TaskConfig 任务调度配置
Task TaskConfig `yaml:"task"`
}
// AppConfig 代表应用基础配置
@@ -106,6 +109,12 @@ type HeartbeatConfig struct {
Concurrency int `yaml:"concurrency"`
}
// TaskConfig 代表任务调度配置
type TaskConfig struct {
Interval int `yaml:"interval"`
NumWorkers int `yaml:"num_workers"`
}
// NewConfig 创建并返回一个新的配置实例
func NewConfig() *Config {
// 默认值可以在这里设置,但我们优先使用配置文件中的值

View File

@@ -15,32 +15,32 @@ type ExecutionLogRepository interface {
FindTaskExecutionLogByID(id uint) (*models.TaskExecutionLog, error)
}
// executionLogRepository 是使用 GORM 的具体实现。
type executionLogRepository struct {
// gormExecutionLogRepository 是使用 GORM 的具体实现。
type gormExecutionLogRepository struct {
db *gorm.DB
}
// NewExecutionLogRepository 创建一个新的执行日志仓库。
// NewGormExecutionLogRepository 创建一个新的执行日志仓库。
// 它接收一个 GORM DB 实例作为依赖。
func NewExecutionLogRepository(db *gorm.DB) ExecutionLogRepository {
return &executionLogRepository{db: db}
func NewGormExecutionLogRepository(db *gorm.DB) ExecutionLogRepository {
return &gormExecutionLogRepository{db: db}
}
// CreatePlanExecutionLog 为一次计划执行创建一条新的日志条目。
func (r *executionLogRepository) CreatePlanExecutionLog(log *models.PlanExecutionLog) error {
func (r *gormExecutionLogRepository) CreatePlanExecutionLog(log *models.PlanExecutionLog) error {
return r.db.Create(log).Error
}
// UpdatePlanExecutionLog 使用 Updates 方法更新一个计划执行日志。
// GORM 的 Updates 传入 struct 时,只会更新非零值字段。
// 在这里,我们期望传入的对象一定包含一个有效的 ID。
func (r *executionLogRepository) UpdatePlanExecutionLog(log *models.PlanExecutionLog) error {
func (r *gormExecutionLogRepository) UpdatePlanExecutionLog(log *models.PlanExecutionLog) error {
return r.db.Updates(log).Error
}
// CreateTaskExecutionLogsInBatch 在一次数据库调用中创建多个任务执行日志条目。
// 这是“预写日志”步骤的关键。
func (r *executionLogRepository) CreateTaskExecutionLogsInBatch(logs []*models.TaskExecutionLog) error {
func (r *gormExecutionLogRepository) CreateTaskExecutionLogsInBatch(logs []*models.TaskExecutionLog) error {
// GORM 的 Create 传入一个切片指针会执行批量插入。
return r.db.Create(&logs).Error
}
@@ -48,13 +48,13 @@ func (r *executionLogRepository) CreateTaskExecutionLogsInBatch(logs []*models.T
// UpdateTaskExecutionLog 使用 Updates 方法更新一个任务执行日志。
// GORM 的 Updates 传入 struct 时,只会更新非零值字段。
// 这种方式代码更直观,上层服务可以直接修改模型对象后进行保存。
func (r *executionLogRepository) UpdateTaskExecutionLog(log *models.TaskExecutionLog) error {
func (r *gormExecutionLogRepository) UpdateTaskExecutionLog(log *models.TaskExecutionLog) error {
return r.db.Updates(log).Error
}
// FindTaskExecutionLogByID 根据 ID 查找单个任务执行日志。
// 它会预加载关联的 Task 信息。
func (r *executionLogRepository) FindTaskExecutionLogByID(id uint) (*models.TaskExecutionLog, error) {
func (r *gormExecutionLogRepository) FindTaskExecutionLogByID(id uint) (*models.TaskExecutionLog, error) {
var log models.TaskExecutionLog
// 使用 Preload("Task") 来确保关联的任务信息被一并加载
err := r.db.Preload("Task").First(&log, id).Error

View File

@@ -18,23 +18,23 @@ type PendingTaskRepository interface {
RequeueTask(originalPendingTask *models.PendingTask) error
}
// pendingTaskRepository 是使用 GORM 的具体实现。
type pendingTaskRepository struct {
// gormPendingTaskRepository 是使用 GORM 的具体实现。
type gormPendingTaskRepository struct {
db *gorm.DB
}
// NewPendingTaskRepository 创建一个新的待执行任务队列仓库。
func NewPendingTaskRepository(db *gorm.DB) PendingTaskRepository {
return &pendingTaskRepository{db: db}
// NewGormPendingTaskRepository 创建一个新的待执行任务队列仓库。
func NewGormPendingTaskRepository(db *gorm.DB) PendingTaskRepository {
return &gormPendingTaskRepository{db: db}
}
// CreatePendingTasksInBatch 在一次数据库调用中创建多个待执行任务条目。
func (r *pendingTaskRepository) CreatePendingTasksInBatch(tasks []*models.PendingTask) error {
func (r *gormPendingTaskRepository) CreatePendingTasksInBatch(tasks []*models.PendingTask) error {
return r.db.Create(&tasks).Error
}
// ClaimNextAvailableTask 以原子方式认领下一个可用的任务。
func (r *pendingTaskRepository) ClaimNextAvailableTask(excludePlanIDs []uint) (*models.TaskExecutionLog, *models.PendingTask, error) {
func (r *gormPendingTaskRepository) ClaimNextAvailableTask(excludePlanIDs []uint) (*models.TaskExecutionLog, *models.PendingTask, error) {
var log models.TaskExecutionLog
var pendingTask models.PendingTask
@@ -79,7 +79,7 @@ func (r *pendingTaskRepository) ClaimNextAvailableTask(excludePlanIDs []uint) (*
// RequeueTask 安全地将一个任务重新放回队列。
// 它通过将原始 PendingTask 的 ID 重置为 0并重新创建它来实现。
func (r *pendingTaskRepository) RequeueTask(originalPendingTask *models.PendingTask) error {
func (r *gormPendingTaskRepository) RequeueTask(originalPendingTask *models.PendingTask) error {
return r.db.Transaction(func(tx *gorm.DB) error {
// 1. 将日志状态恢复为 waiting
if err := tx.Model(&models.TaskExecutionLog{}).Where("id = ?", originalPendingTask.TaskExecutionLogID).Update("status", models.ExecutionStatusWaiting).Error; err != nil {