基于time包封装定时器

package cron

import (
    "context"
    "runtime/debug"
    "sync"
    "time"
)

type Timer struct {
    ctx         context.Context
    cancel      context.CancelFunc
    timer       *time.Timer
    process     func()
    mu          sync.Mutex
    concurrency int
    sem         chan struct{}
    startHour   int
    endHour     int
    enabled     bool
    duration    time.Duration
}

func NewTimer(duration time.Duration, process func(), concurrent, startHour, endHour int) *Timer {
    ctx, cancel := context.WithCancel(context.Background())
    timer := time.NewTimer(duration)
    return &Timer{
        ctx:         ctx,
        cancel:      cancel,
        timer:       timer,
        process:     process,
        concurrency: concurrent,
        sem:         make(chan struct{}, concurrent),
        startHour:   startHour,
        endHour:     endHour,
        enabled:     true,
        duration:    duration,
    }
}

func (t *Timer) shouldProcess() bool {
    now := time.Now().Hour()
    return now >= t.startHour && now <= t.endHour
}

func (t *Timer) Start() {
    if t.ctx.Err() != nil {
        return
    }
    for {
        select {
        case <-t.timer.C:
            t.timer.Reset(t.duration)
            t.processIfEnabled()
        case <-t.ctx.Done():
            return
        }
    }
}

func (t *Timer) processIfEnabled() {
    t.mu.Lock()
    defer t.mu.Unlock()
    if t.process != nil && t.shouldProcess() && t.enabled {
        t.sem <- struct{}{}
        go func() {
            defer func() {
                <-t.sem
                t.ThrowException()
            }()
            t.process()
        }()
    }
}

func (t *Timer) Enable() {
    t.mu.Lock()
    defer t.mu.Unlock()
    t.enabled = true
}

func (t *Timer) Disable() {
    t.mu.Lock()
    defer t.mu.Unlock()
    t.enabled = false
}

func (t *Timer) Stop() {
    t.timer.Stop()
    t.cancel()
}

func (t *Timer) ThrowException() {
    if r := recover(); r != nil {
        debug.PrintStack()
    }
}
本作品采用《CC 协议》,转载必须注明作者和本文链接
goStruct
讨论数量: 0
(= ̄ω ̄=)··· 暂无内容!

讨论应以学习和精进为目的。请勿发布不友善或者负能量的内容,与人为善,比聪明更重要!