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