后台定时任务处理器__Golang

func main() {
    ctx, cancel := context.WithCancel(context.Background())
    defer cancel()

    r := NewTriggerableTaskRunner(10*time.Second, func(ctx context.Context) {
       fmt.Println("任务执行于:", time.Now())
    })

    r.Start(ctx)

    // 模拟手动触发
    time.Sleep(3 * time.Second)
    fmt.Println("手动触发")
    r.Trigger()

    // 等待几秒后退出
    time.Sleep(60 * time.Second)
}

// TriggerableTaskRunner 是一个通用的后台任务执行器,支持定时触发 + 外部触发 + 上下文控制退出。
type TriggerableTaskRunner struct {
    triggerChan chan struct{}
    interval    time.Duration
    task        func(context.Context)
}

// NewTriggerableTaskRunner 创建一个新的任务执行器。
// task:需要执行的任务函数(接收 context)。
// interval:定时执行的间隔时间。
func NewTriggerableTaskRunner(interval time.Duration, task func(context.Context)) *TriggerableTaskRunner {
    return &TriggerableTaskRunner{
       triggerChan: make(chan struct{}, 1), // 缓冲大小为1,即只能同时只能接受一个信号
       interval:    interval,
       task:        task,
    }
}

// Start 启动任务执行器,会在后台协程中运行。
// 通过 context 控制生命周期,ctx 被取消后会自动退出。
func (r *TriggerableTaskRunner) Start(ctx context.Context) {
    go func() {
       ticker := time.NewTicker(r.interval)
       defer ticker.Stop()

       for {
          select {
          case <-r.triggerChan:
             r.task(ctx)
          case <-ticker.C:
             r.task(ctx)
          case <-ctx.Done():
             return
          }
       }
    }()
}

// Trigger 触发一次任务执行(非阻塞)。
func (r *TriggerableTaskRunner) Trigger() {
    select {
    // triggerChan通道未满,发送一个空结构体对象
    case r.triggerChan <- struct{}{}:
    default: // 忽略多余的触发
    }
}

 

支持定时触发,手动触发,主程序结束安全退出。

posted @ 2025-04-29 23:12  Ashe|||^_^  阅读(0)  评论(0)    收藏  举报