109 lines
2.5 KiB
Go
109 lines
2.5 KiB
Go
// Package crontask/job_manager.go 任务管理文件
|
||
package crontask
|
||
|
||
import (
|
||
"fmt"
|
||
"log"
|
||
"time"
|
||
)
|
||
|
||
// LoadJobs 加载数据库中的定时任务
|
||
func (cm *CronManager) LoadJobs() error {
|
||
const query = `
|
||
SELECT id, name, schedule, handler, enabled
|
||
FROM admin_cron_jobs
|
||
WHERE enabled = ?
|
||
AND isdel = 0
|
||
`
|
||
|
||
var jobs []CronJob
|
||
err := cm.db.Select(&jobs, query, 1)
|
||
if err != nil {
|
||
return err
|
||
}
|
||
|
||
log.Printf("Loaded %d enabled cron jobs", len(jobs))
|
||
|
||
for _, job := range jobs {
|
||
if err := cm.AddJob(job); err != nil {
|
||
log.Printf("Failed to add job %s: %v", job.Name, err)
|
||
}
|
||
}
|
||
return nil
|
||
}
|
||
|
||
// AddJob 添加定时任务
|
||
func (cm *CronManager) AddJob(job CronJob) error {
|
||
// 如果该任务已存在,先移除旧的任务
|
||
if entryID, exists := cm.entries[job.ID]; exists {
|
||
cm.cron.Remove(entryID)
|
||
delete(cm.entries, job.ID)
|
||
log.Printf("移除已存在的任务: %s (ID: %d)", job.Name, job.ID)
|
||
}
|
||
|
||
handler, exists := cm.handlers[job.Handler]
|
||
if !exists {
|
||
return fmt.Errorf("handler %s not found", job.Handler)
|
||
}
|
||
|
||
entryID, err := cm.cron.AddFunc(job.Schedule, func() {
|
||
cm.executeJob(job, handler)
|
||
})
|
||
if err != nil {
|
||
return err
|
||
}
|
||
|
||
cm.entries[job.ID] = entryID
|
||
log.Printf("Added job %s with ID %d", job.Name, job.ID)
|
||
return nil
|
||
}
|
||
|
||
// executeJob 执行定时任务
|
||
func (cm *CronManager) executeJob(job CronJob, handler JobHandler) {
|
||
// 检查上下文是否已取消
|
||
select {
|
||
case <-cm.ctx.Done():
|
||
log.Printf("Job %s cancelled before execution", job.Name)
|
||
return
|
||
default:
|
||
}
|
||
|
||
startTime := time.Now()
|
||
status := "success"
|
||
var message string
|
||
|
||
// 执行任务(如果任务支持上下文取消,应传递 cm.ctx)
|
||
err := handler()
|
||
if err != nil {
|
||
status = "failed"
|
||
message = err.Error()
|
||
log.Printf("Job %s execution failed: %v", job.Name, err)
|
||
}
|
||
|
||
// 检查任务是否在执行过程中被取消
|
||
select {
|
||
case <-cm.ctx.Done():
|
||
log.Printf("Job %s was cancelled during execution", job.Name)
|
||
return
|
||
default:
|
||
}
|
||
|
||
// 创建 endTime 变量以便获取其地址
|
||
endTime := time.Now()
|
||
|
||
// 记录执行日志
|
||
logEntry := CronJobLog{
|
||
JobID: job.ID,
|
||
Status: status,
|
||
Message: message,
|
||
StartTime: &startTime,
|
||
EndTime: &endTime,
|
||
}
|
||
|
||
_, err = cm.db.NamedExec(`INSERT INTO admin_cron_job_logs (job_id, status, message, start_time, end_time)
|
||
VALUES (:job_id, :status, :message, :start_time, :end_time)`, logEntry)
|
||
if err != nil {
|
||
log.Printf("Failed to log job execution: %v", err)
|
||
}
|
||
}
|