|
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687 |
- package tickevent
-
- import (
- "math/rand"
- "sync/atomic"
- "time"
- )
-
- type StartOption struct {
- RandomStartDelayMs int // 第一次任务启动前增加一段随机时长的延迟,随机的最长延迟时间由这个参数指定。如果为0,则不进行延迟。
- }
-
- type ExecuteContext[TArgs any] struct {
- Executor *Executor[TArgs]
- Self *EventTicker[TArgs]
- Args TArgs
- }
-
- type EventTicker[TArgs any] struct {
- event TickEvent[TArgs]
- intervalMs int
- doneChan chan int
- done atomic.Bool
- }
-
- type Executor[TArgs any] struct {
- execArgs TArgs
- }
-
- func NewExecutor[TArgs any](args TArgs) Executor[TArgs] {
- return Executor[TArgs]{
- execArgs: args,
- }
- }
-
- func (e *Executor[TArgs]) Start(event TickEvent[TArgs], intervalMs int, opts ...StartOption) EventTicker[TArgs] {
- opt := StartOption{}
- if len(opts) > 0 {
- opt = opts[0]
- }
-
- ticker := EventTicker[TArgs]{
- event: event,
- intervalMs: intervalMs,
- doneChan: make(chan int),
- done: atomic.Bool{},
- }
- ticker.done.Store(false)
-
- go func() {
- if opt.RandomStartDelayMs > 0 {
- <-time.After(time.Duration(rand.Intn(opt.RandomStartDelayMs)) * time.Millisecond)
- }
-
- timeTicker := time.NewTicker(time.Duration(intervalMs) * time.Millisecond)
-
- loop:
- for {
- select {
- case <-timeTicker.C:
- if ticker.done.Load() {
- break loop
- }
-
- execCtx := ExecuteContext[TArgs]{
- Executor: e,
- Self: &ticker,
- Args: e.execArgs,
- }
- event.Execute(execCtx)
-
- case <-ticker.doneChan:
- break loop
- }
- }
-
- timeTicker.Stop()
- }()
-
- return ticker
- }
-
- func (e *Executor[TArgs]) Stop(ticker EventTicker[TArgs]) {
- ticker.done.Store(true)
- close(ticker.doneChan)
- // 保证在调用此函数结束后,事件不会再被调用
- }
|