135 lines
2.8 KiB
Go
135 lines
2.8 KiB
Go
package cron
|
||
|
||
import (
|
||
"fmt"
|
||
"log"
|
||
"sync"
|
||
|
||
"github.com/robfig/cron/v3"
|
||
)
|
||
|
||
var (
|
||
cronManager *CronManager
|
||
once sync.Once
|
||
)
|
||
|
||
// CronManager 定时任务管理器
|
||
type CronManager struct {
|
||
cron *cron.Cron
|
||
tasks map[string]cron.EntryID
|
||
mu sync.RWMutex
|
||
isRunning bool
|
||
}
|
||
|
||
// GetCronManager 获取定时任务管理器单例
|
||
func GetCronManager() *CronManager {
|
||
once.Do(func() {
|
||
cronManager = &CronManager{
|
||
cron: cron.New(cron.WithSeconds()), // 支持秒级定时
|
||
tasks: make(map[string]cron.EntryID),
|
||
}
|
||
})
|
||
return cronManager
|
||
}
|
||
|
||
// AddTask 添加定时任务
|
||
// name: 任务名称,用于标识任务
|
||
// spec: cron表达式,例如:
|
||
func (cm *CronManager) AddTask(name string, spec string, job func()) error {
|
||
cm.mu.Lock()
|
||
defer cm.mu.Unlock()
|
||
if _, exists := cm.tasks[name]; exists {
|
||
return fmt.Errorf("任务 %s 已存在", name)
|
||
}
|
||
// 添加任务
|
||
entryID, err := cm.cron.AddFunc(spec, func() {
|
||
defer func() {
|
||
if r := recover(); r != nil {
|
||
log.Printf("定时任务 [%s] 执行panic: %v", name, r)
|
||
}
|
||
}()
|
||
log.Printf("定时任务 [%s] 开始执行", name)
|
||
job()
|
||
log.Printf("定时任务 [%s] 执行完成", name)
|
||
})
|
||
|
||
if err != nil {
|
||
return fmt.Errorf("添加任务失败: %v", err)
|
||
}
|
||
cm.tasks[name] = entryID
|
||
log.Printf("定时任务 [%s] 添加成功, cron表达式: %s", name, spec)
|
||
return nil
|
||
}
|
||
|
||
// RemoveTask 移除定时任务
|
||
func (cm *CronManager) RemoveTask(name string) error {
|
||
cm.mu.Lock()
|
||
defer cm.mu.Unlock()
|
||
|
||
entryID, exists := cm.tasks[name]
|
||
if !exists {
|
||
return fmt.Errorf("任务 %s 不存在", name)
|
||
}
|
||
|
||
cm.cron.Remove(entryID)
|
||
delete(cm.tasks, name)
|
||
log.Printf("定时任务 [%s] 已移除", name)
|
||
return nil
|
||
}
|
||
|
||
// Start 启动定时任务管理器
|
||
func (cm *CronManager) Start() {
|
||
cm.mu.Lock()
|
||
defer cm.mu.Unlock()
|
||
|
||
if cm.isRunning {
|
||
log.Println("定时任务管理器已经在运行中")
|
||
return
|
||
}
|
||
|
||
cm.cron.Start()
|
||
cm.isRunning = true
|
||
log.Printf("定时任务管理器已启动,当前任务数: %d", len(cm.tasks))
|
||
}
|
||
|
||
// Stop 停止定时任务管理器
|
||
func (cm *CronManager) Stop() {
|
||
cm.mu.Lock()
|
||
defer cm.mu.Unlock()
|
||
|
||
if !cm.isRunning {
|
||
return
|
||
}
|
||
|
||
ctx := cm.cron.Stop()
|
||
<-ctx.Done()
|
||
cm.isRunning = false
|
||
log.Println("定时任务管理器已停止")
|
||
}
|
||
|
||
// IsRunning 检查是否在运行
|
||
func (cm *CronManager) IsRunning() bool {
|
||
cm.mu.RLock()
|
||
defer cm.mu.RUnlock()
|
||
return cm.isRunning
|
||
}
|
||
|
||
// GetTaskCount 获取任务数量
|
||
func (cm *CronManager) GetTaskCount() int {
|
||
cm.mu.RLock()
|
||
defer cm.mu.RUnlock()
|
||
return len(cm.tasks)
|
||
}
|
||
|
||
// ListTasks 列出所有任务名称
|
||
func (cm *CronManager) ListTasks() []string {
|
||
cm.mu.RLock()
|
||
defer cm.mu.RUnlock()
|
||
|
||
taskNames := make([]string, 0, len(cm.tasks))
|
||
for name := range cm.tasks {
|
||
taskNames = append(taskNames, name)
|
||
}
|
||
return taskNames
|
||
}
|