123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899 |
- // 定时协程
- // 定时或发通知调用协程函数
- package coroutine
- import (
- "context"
- "leafstalk/log"
- "sync"
- "time"
- )
- // TimerRoutine 定时协程类
- type TimerRoutine struct {
- name string
- interval time.Duration
- chEvent chan struct{}
- wg sync.WaitGroup
- cancel context.CancelFunc
- taskFunc func() // 定时执行的任务函数
- }
- // NewTimerRoutine 创建一个定时协程实例
- func NewTimerRoutine(name string, interval time.Duration, taskFunc func()) *TimerRoutine {
- return &TimerRoutine{
- name: name,
- interval: interval,
- chEvent: make(chan struct{}, 1),
- taskFunc: taskFunc,
- }
- }
- // Start 启动定时协程
- func (tr *TimerRoutine) Start() {
- ctx, cancel := context.WithCancel(context.Background())
- tr.cancel = cancel
- tr.wg.Add(1)
- go func() {
- defer func() {
- tr.wg.Done()
- log.Infof("TimerRoutine.Start exit %s", tr.name)
- }()
- tr.run(ctx)
- }()
- }
- // Stop 停止定时协程,等待协程退出
- func (tr *TimerRoutine) Stop() {
- tr.cancel()
- tr.wg.Wait()
- }
- // Notify 发送事件通知,触发任务执行
- func (tr *TimerRoutine) Notify() {
- select {
- case tr.chEvent <- struct{}{}:
- default:
- }
- }
- // run 定时协程的核心逻辑
- func (tr *TimerRoutine) run(ctx context.Context) {
- ticker := time.NewTicker(tr.interval)
- defer func() {
- ticker.Stop()
- log.Infof("TimerRoutine.run exit %s", tr.name)
- }()
- safeDo := func() {
- defer func() {
- if err := recover(); err != nil {
- // 处理 panic,例如记录日志
- log.Infof("TimerRoutine recover panic %s: %v", tr.name, err)
- }
- }()
- tr.taskFunc()
- }
- for {
- select {
- case <-ctx.Done():
- return
- case <-ticker.C:
- case <-tr.chEvent:
- }
- if tr.taskFunc != nil {
- safeDo()
- }
- }
- }
- func example1() {
- timerRoutine := NewTimerRoutine("MyTimer", time.Second*5, func() {
- })
- timerRoutine.Start()
- timerRoutine.Stop()
- }
|