123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111 |
- // Copyright 2021 Tencent Inc. All rights reserved.
- package task
- import (
- "runtime"
- "sync"
- "time"
- )
- // State RepeatedTask 状态类型
- type State int
- // State 可能枚举
- const (
- Init State = iota
- Running
- Stopped
- )
- // implRepeatedTask 定时重复任务
- // 将会在后台(另一个goroutine中)定时重复执行给定的任务
- //
- // 注意:
- // 1. 请不要在多个协程中操作同一个 implRepeatedTask 实例,它并不支持多协程并发
- // 2. 基于上一条,请不要在 handler 中操作本 implRepeatedTask 实例
- type implRepeatedTask struct {
- interval time.Duration
- handler func(time.Time)
- state State
- ticker *time.Ticker
- closed chan struct{}
- wg sync.WaitGroup
- }
- // State 查看当前任务状态
- func (t *implRepeatedTask) State() State {
- return t.state
- }
- // Interval 查看当前任务间隔
- func (t *implRepeatedTask) Interval() time.Duration {
- return t.interval
- }
- // Start 启动重复任务
- // 当且仅当任务并未启动时有效,其他状态下不会发生任何事
- func (t *implRepeatedTask) Start() {
- if t.state != Init {
- return
- }
- t.ticker = time.NewTicker(t.interval)
- t.wg.Add(1)
- go func() {
- defer t.wg.Done()
- t.run()
- }()
- t.state = Running
- }
- // Stop 停止重复任务
- // 当且仅当任务处于 Running 状态时有效,其他状态下不会发生任何事
- func (t *implRepeatedTask) Stop() {
- if t.state != Running {
- return
- }
- close(t.closed)
- t.wg.Wait()
- t.ticker.Stop()
- t.state = Stopped
- }
- func (t *implRepeatedTask) run() {
- for {
- select {
- case <-t.closed:
- return
- case tickTime := <-t.ticker.C:
- t.handler(tickTime)
- }
- }
- }
- type wrapper struct {
- *implRepeatedTask
- }
- // RepeatedTask 自动重复任务
- // 设定间隔时间与任务Handler即可自动按间隔执行,在你不再持有该实例的引用后,任务自动停止。
- // 也可以调用 Stop 方法来停止任务
- type RepeatedTask wrapper
- // NewRepeatedTask 初始化一个自动重复任务
- // 创建成功后请调用 Start 方法启动任务,启动后需等待 interval 时间发生第一次调用
- func NewRepeatedTask(interval time.Duration, handler func(time.Time)) *RepeatedTask {
- task := implRepeatedTask{
- closed: make(chan struct{}),
- interval: interval,
- handler: handler,
- }
- result := &RepeatedTask{&task}
- runtime.SetFinalizer(result, func(t *RepeatedTask) { t.Stop() })
- return result
- }
|