package crontab import ( "apiServer_service/utils/logger" "fmt" "sync" "github.com/robfig/cron/v3" ) // Task 定时任务接口 type Task interface { Name() string Spec() string Run() } type Scheduler struct { cron *cron.Cron tasks []Task mu sync.RWMutex } var ( defaultScheduler *Scheduler once sync.Once ) func DefaultScheduler() *Scheduler { once.Do(func() { defaultScheduler = NewScheduler() }) return defaultScheduler } func NewScheduler() *Scheduler { return &Scheduler{ cron: cron.New(cron.WithSeconds()), } } func (s *Scheduler) Register(task Task) { s.mu.Lock() defer s.mu.Unlock() entryID, err := s.cron.AddFunc(task.Spec(), func() { logger.CronInfo("Cron", fmt.Sprintf("执行任务: %s", task.Name())) defer func() { if r := recover(); r != nil { logger.CronError("Cron", fmt.Sprintf("任务 %s panic: %v", task.Name(), r)) } }() task.Run() }) if err != nil { logger.CronError("Cron", fmt.Sprintf("注册任务失败: %s, %v", task.Name(), err)) return } s.tasks = append(s.tasks, task) logger.CronInfo("Cron", fmt.Sprintf("注册任务: %s [%s] (id=%d)", task.Name(), task.Spec(), entryID)) } func (s *Scheduler) Start() { logger.CronInfo("Cron", fmt.Sprintf("调度器启动,已注册 %d 个任务", len(s.tasks))) s.cron.Start() } func (s *Scheduler) Stop() { logger.CronInfo("Cron", "调度器停止") ctx := s.cron.Stop() <-ctx.Done() } func (s *Scheduler) RunOnce() { s.mu.RLock() defer s.mu.RUnlock() for _, task := range s.tasks { logger.CronInfo("Cron", fmt.Sprintf("立即执行: %s", task.Name())) task.Run() } } func (s *Scheduler) RunTaskByName(name string) bool { s.mu.RLock() defer s.mu.RUnlock() for _, task := range s.tasks { if task.Name() == name { task.Run() return true } } return false } func (s *Scheduler) GetTasks() []Task { s.mu.RLock() defer s.mu.RUnlock() return s.tasks }