Files
apiServer-service/crontab/scheduler.go
T
shiran aa9f892a32 feat: 添加数据库集成、定时任务调度器和事件Hook体系
- 新增数据库配置项(DB_TYPE, DB_HOST, DB_PORT等),支持MySQL和PostgreSQL
- 集成GORM实现数据库连接和自动迁移功能
- 添加定时任务调度器(cmd/scheduler),基于robfig/cron实现秒级调度
- 实现事件Hook体系,支持同步/异步处理和优先级排序
- 更新构建脚本,编译server、cli、scheduler三个二进制文件
- 配置systemd服务管理定时任务调度器
- 重构项目结构,新增crontab和hooks目录模块
- 更新README文档,完善各组件使用说明和部署配置
2026-04-15 12:39:59 +08:00

100 lines
1.9 KiB
Go

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
}