feat: timer.Ticker 新增 Cron 函数,支持通过 Cron 表达式下发定时任务
This commit is contained in:
parent
844fb3059e
commit
4117607c8f
1
go.mod
1
go.mod
|
@ -36,6 +36,7 @@ require (
|
|||
github.com/goccy/go-json v0.10.2 // indirect
|
||||
github.com/golang/protobuf v1.5.3 // indirect
|
||||
github.com/gopherjs/gopherjs v1.17.2 // indirect
|
||||
github.com/gorhill/cronexpr v0.0.0-20180427100037-88b0669f7d75 // indirect
|
||||
github.com/inconshreveable/mousetrap v1.1.0 // indirect
|
||||
github.com/jonboulle/clockwork v0.3.0 // indirect
|
||||
github.com/jtolds/gls v4.20.0+incompatible // indirect
|
||||
|
|
4
go.sum
4
go.sum
|
@ -76,6 +76,8 @@ github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeN
|
|||
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
|
||||
github.com/gopherjs/gopherjs v1.17.2 h1:fQnZVsXk8uxXIStYb0N4bGk7jeyTalG/wsZjQ25dO0g=
|
||||
github.com/gopherjs/gopherjs v1.17.2/go.mod h1:pRRIvn/QzFLrKfvEz3qUuEhtE/zLCWfreZ6J5gM2i+k=
|
||||
github.com/gorhill/cronexpr v0.0.0-20180427100037-88b0669f7d75 h1:f0n1xnMSmBLzVfsMMvriDyA75NB/oBgILX2GcHXIQzY=
|
||||
github.com/gorhill/cronexpr v0.0.0-20180427100037-88b0669f7d75/go.mod h1:g2644b03hfBX9Ov0ZBDgXXens4rxSxmqFBbhvKv2yVA=
|
||||
github.com/gorilla/websocket v1.5.0 h1:PPwGk2jz7EePpoHN/+ClbZu8SPxiqlu12wZP/3sWmnc=
|
||||
github.com/gorilla/websocket v1.5.0/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
|
||||
github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8=
|
||||
|
@ -132,6 +134,8 @@ github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINE
|
|||
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||
github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
|
||||
github.com/robfig/cron/v3 v3.0.1 h1:WdRxkvbJztn8LMz/QEvLN5sBU+xKpSqwwUO1Pjr4qDs=
|
||||
github.com/robfig/cron/v3 v3.0.1/go.mod h1:eQICP3HwyT7UooqI/z+Ov+PtYAWygg1TEWWzGIFLtro=
|
||||
github.com/rogpeppe/go-internal v1.6.1/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc=
|
||||
github.com/rogpeppe/go-internal v1.8.0/go.mod h1:WmiCO8CzOY8rg0OYDC4/i/2WRWAB6poM+XZ2dLUbcbE=
|
||||
github.com/rogpeppe/go-internal v1.9.0 h1:73kH8U+JUqXU8lRuOHeVHaa/SZPifC7BkcraZVejAe8=
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
package timer
|
||||
|
||||
import (
|
||||
"github.com/gorhill/cronexpr"
|
||||
"reflect"
|
||||
"sync"
|
||||
"time"
|
||||
|
@ -26,6 +27,8 @@ type Scheduler struct {
|
|||
ticker *Ticker
|
||||
|
||||
lock sync.RWMutex
|
||||
|
||||
expr *cronexpr.Expression
|
||||
}
|
||||
|
||||
// Name 获取调度器名称
|
||||
|
@ -38,9 +41,13 @@ func (slf *Scheduler) Next(prev time.Time) time.Time {
|
|||
slf.lock.RLock()
|
||||
defer slf.lock.RUnlock()
|
||||
|
||||
if slf.kill || (slf.total > 0 && slf.trigger > slf.total) {
|
||||
if slf.kill || (slf.expr != nil && slf.total > 0 && slf.trigger > slf.total) {
|
||||
return time.Time{}
|
||||
}
|
||||
if slf.expr != nil {
|
||||
next := slf.expr.Next(prev)
|
||||
return next
|
||||
}
|
||||
if slf.trigger == 0 {
|
||||
slf.trigger++
|
||||
return prev.Add(slf.after)
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
package timer
|
||||
|
||||
import (
|
||||
"github.com/gorhill/cronexpr"
|
||||
"reflect"
|
||||
"sync"
|
||||
"time"
|
||||
|
@ -72,20 +73,33 @@ func (slf *Ticker) GetSchedulers() []string {
|
|||
return names
|
||||
}
|
||||
|
||||
// Cron 通过 cron 表达式设置一个调度器,当 cron 表达式错误时,将会引发 panic
|
||||
func (slf *Ticker) Cron(name, expression string, handleFunc interface{}, args ...interface{}) {
|
||||
expr := cronexpr.MustParse(expression)
|
||||
slf.loop(name, 0, 0, expr, 0, handleFunc, args...)
|
||||
}
|
||||
|
||||
// After 设置一个在特定时间后运行一次的调度器
|
||||
func (slf *Ticker) After(name string, after time.Duration, handleFunc interface{}, args ...interface{}) {
|
||||
slf.Loop(name, after, timingWheelTick, 1, handleFunc, args...)
|
||||
slf.loop(name, after, timingWheelTick, nil, 1, handleFunc, args...)
|
||||
}
|
||||
|
||||
// Loop 设置一个在特定时间后反复运行的调度器
|
||||
func (slf *Ticker) Loop(name string, after, interval time.Duration, times int, handleFunc interface{}, args ...interface{}) {
|
||||
slf.loop(name, after, interval, nil, times, handleFunc, args...)
|
||||
}
|
||||
|
||||
// Loop 设置一个在特定时间后反复运行的调度器
|
||||
func (slf *Ticker) loop(name string, after, interval time.Duration, expr *cronexpr.Expression, times int, handleFunc interface{}, args ...interface{}) {
|
||||
slf.StopTimer(name)
|
||||
|
||||
if after < timingWheelTick {
|
||||
after = timingWheelTick
|
||||
}
|
||||
if interval < timingWheelTick {
|
||||
interval = timingWheelTick
|
||||
if expr == nil {
|
||||
if after < timingWheelTick {
|
||||
after = timingWheelTick
|
||||
}
|
||||
if interval < timingWheelTick {
|
||||
interval = timingWheelTick
|
||||
}
|
||||
}
|
||||
|
||||
var values = make([]reflect.Value, len(args))
|
||||
|
@ -101,6 +115,7 @@ func (slf *Ticker) Loop(name string, after, interval time.Duration, times int, h
|
|||
cbFunc: reflect.ValueOf(handleFunc),
|
||||
cbArgs: values,
|
||||
ticker: slf,
|
||||
expr: expr,
|
||||
}
|
||||
|
||||
slf.lock.Lock()
|
||||
|
|
|
@ -0,0 +1,25 @@
|
|||
package timer_test
|
||||
|
||||
import (
|
||||
"github.com/kercylan98/minotaur/utils/timer"
|
||||
"github.com/kercylan98/minotaur/utils/times"
|
||||
"testing"
|
||||
"time"
|
||||
)
|
||||
|
||||
func TestTicker_Cron(t *testing.T) {
|
||||
ticker := timer.GetTicker(10)
|
||||
ticker.After("1_sec", time.Second, func() {
|
||||
t.Log(time.Now().Format(time.DateTime), "1_sec")
|
||||
})
|
||||
|
||||
ticker.Loop("1_sec_loop_3", 0, time.Second, 3, func() {
|
||||
t.Log(time.Now().Format(time.DateTime), "1_sec_loop_3")
|
||||
})
|
||||
|
||||
ticker.Cron("5_sec_cron", "0/5 * * * * * ?", func() {
|
||||
t.Log(time.Now().Format(time.DateTime), "5_sec_cron")
|
||||
})
|
||||
|
||||
time.Sleep(times.Week)
|
||||
}
|
Loading…
Reference in New Issue