2024-04-04 10:58:57 +08:00
|
|
|
package timerx
|
|
|
|
|
|
2025-07-24 17:13:17 +08:00
|
|
|
import (
|
|
|
|
|
"time"
|
|
|
|
|
|
2025-10-05 16:30:41 +08:00
|
|
|
"github.com/robfig/cron/v3"
|
2025-07-24 17:13:17 +08:00
|
|
|
"github.com/yuninks/timerx/logger"
|
|
|
|
|
)
|
2024-05-30 11:02:44 +08:00
|
|
|
|
2024-04-04 10:58:57 +08:00
|
|
|
type Options struct {
|
2025-10-10 21:03:00 +08:00
|
|
|
logger logger.Logger
|
|
|
|
|
location *time.Location
|
|
|
|
|
timeout time.Duration // 任务最长执行时间
|
|
|
|
|
usePriority bool
|
|
|
|
|
priorityVal int64
|
|
|
|
|
batchSize int
|
2025-10-14 11:13:12 +08:00
|
|
|
maxRunCount int // 单个任务最大运行次数 0代表不限
|
|
|
|
|
maxWorkers int // 最大工作协程数
|
2025-10-10 21:03:00 +08:00
|
|
|
cronParser *cron.Parser // cron表达式解析器
|
2024-04-04 10:58:57 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func defaultOptions() Options {
|
2025-10-05 16:30:41 +08:00
|
|
|
|
2025-10-05 16:33:23 +08:00
|
|
|
// 默认使用Linux的定时任务兼容
|
|
|
|
|
parser := cron.NewParser(cron.Minute | cron.Hour | cron.Dom | cron.Month | cron.Dow)
|
2025-10-05 16:30:41 +08:00
|
|
|
|
2024-04-04 10:58:57 +08:00
|
|
|
return Options{
|
2025-10-10 21:03:00 +08:00
|
|
|
logger: logger.NewLogger(),
|
|
|
|
|
location: time.Local,
|
|
|
|
|
timeout: time.Hour, //
|
|
|
|
|
usePriority: false,
|
|
|
|
|
priorityVal: 0,
|
|
|
|
|
batchSize: 100,
|
|
|
|
|
maxRunCount: 0,
|
2025-10-14 11:13:12 +08:00
|
|
|
maxWorkers: 100,
|
2025-10-10 21:03:00 +08:00
|
|
|
cronParser: &parser,
|
2024-04-04 10:58:57 +08:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
type Option func(*Options)
|
|
|
|
|
|
2025-10-10 21:03:00 +08:00
|
|
|
// 返回带默认值的配置
|
2024-04-04 10:58:57 +08:00
|
|
|
func newOptions(opts ...Option) Options {
|
|
|
|
|
o := defaultOptions()
|
|
|
|
|
for _, opt := range opts {
|
|
|
|
|
opt(&o)
|
|
|
|
|
}
|
|
|
|
|
return o
|
|
|
|
|
}
|
|
|
|
|
|
2025-10-10 21:03:00 +08:00
|
|
|
// 返回空的配置
|
|
|
|
|
func newEmptyOptions(opts ...Option) Options {
|
|
|
|
|
o := Options{}
|
|
|
|
|
for _, opt := range opts {
|
|
|
|
|
opt(&o)
|
|
|
|
|
}
|
|
|
|
|
return o
|
|
|
|
|
}
|
|
|
|
|
|
2024-05-07 20:26:13 +08:00
|
|
|
// 设置日志
|
2025-09-24 14:50:30 +08:00
|
|
|
func WithLogger(log logger.Logger) Option {
|
2024-04-04 10:58:57 +08:00
|
|
|
return func(o *Options) {
|
|
|
|
|
o.logger = log
|
|
|
|
|
}
|
|
|
|
|
}
|
2024-05-07 20:26:13 +08:00
|
|
|
|
|
|
|
|
// 设定时区
|
2025-09-24 14:50:30 +08:00
|
|
|
func WithLocation(zone *time.Location) Option {
|
2024-05-07 20:26:13 +08:00
|
|
|
return func(o *Options) {
|
2024-05-30 11:02:44 +08:00
|
|
|
o.location = zone
|
2024-05-07 20:26:13 +08:00
|
|
|
}
|
|
|
|
|
}
|
2024-06-22 15:34:49 +08:00
|
|
|
|
|
|
|
|
// 设置任务最长执行时间
|
2025-09-24 14:50:30 +08:00
|
|
|
func WithTimeout(d time.Duration) Option {
|
2024-06-22 15:34:49 +08:00
|
|
|
return func(o *Options) {
|
|
|
|
|
o.timeout = d
|
|
|
|
|
}
|
|
|
|
|
}
|
2025-06-11 15:12:08 +08:00
|
|
|
|
|
|
|
|
// 设置优先级
|
2025-09-24 14:50:30 +08:00
|
|
|
func WithPriority(priority int64) Option {
|
2025-06-11 15:12:08 +08:00
|
|
|
return func(o *Options) {
|
2025-08-27 15:52:09 +08:00
|
|
|
o.usePriority = true
|
|
|
|
|
o.priorityVal = priority
|
2025-06-11 15:12:08 +08:00
|
|
|
}
|
|
|
|
|
}
|
2025-09-24 14:50:30 +08:00
|
|
|
|
|
|
|
|
func WithBatchSize(size int) Option {
|
|
|
|
|
return func(o *Options) {
|
|
|
|
|
if size <= 1 {
|
|
|
|
|
size = 1
|
|
|
|
|
}
|
|
|
|
|
o.batchSize = size
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func WithMaxRetryCount(count int) Option {
|
|
|
|
|
return func(o *Options) {
|
2025-09-24 17:26:33 +08:00
|
|
|
if count < 0 {
|
|
|
|
|
count = 0
|
2025-09-24 14:50:30 +08:00
|
|
|
}
|
2025-10-10 21:03:00 +08:00
|
|
|
o.maxRunCount = count
|
2025-09-24 14:50:30 +08:00
|
|
|
}
|
|
|
|
|
}
|
2025-10-05 16:30:41 +08:00
|
|
|
|
2025-10-14 11:13:12 +08:00
|
|
|
func WithMaxWorkers(count int) Option {
|
|
|
|
|
return func(o *Options) {
|
|
|
|
|
if count < 0 {
|
|
|
|
|
count = 10
|
|
|
|
|
}
|
|
|
|
|
o.maxWorkers = count
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2025-10-05 16:30:41 +08:00
|
|
|
// 添加cron表达式解析器
|
|
|
|
|
func WithCronParser(parser cron.Parser) Option {
|
|
|
|
|
return func(o *Options) {
|
|
|
|
|
o.cronParser = &parser
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 设置cron表达式解析器 秒级
|
|
|
|
|
// "*/5 * * * * ?" => 每隔5秒执行一次
|
|
|
|
|
// "0 0 0 * * ?" => 每天零点执行一次
|
|
|
|
|
// "0 0 0 1 * ?" => 每月1日零点执行一次
|
|
|
|
|
// "0 */5 * * * ?" => 每隔5分钟执行一次
|
|
|
|
|
func WithCronParserSecond() Option {
|
|
|
|
|
return func(o *Options) {
|
|
|
|
|
parser := cron.NewParser(cron.Second | cron.Minute | cron.Hour | cron.Dom | cron.Month | cron.Dow | cron.Descriptor)
|
|
|
|
|
o.cronParser = &parser
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 设置cron表达式解析器
|
|
|
|
|
// cron.Second | cron.Minute | cron.Hour | cron.Dom | cron.Month | cron.Dow | cron.Descriptor
|
|
|
|
|
func WithCronParserOption(options cron.ParseOption) Option {
|
|
|
|
|
return func(o *Options) {
|
|
|
|
|
parser := cron.NewParser(options)
|
|
|
|
|
o.cronParser = &parser
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Cron表达式 与Linux的定时任务兼容
|
|
|
|
|
func WithCronParserLinux() Option {
|
|
|
|
|
return func(o *Options) {
|
|
|
|
|
parser := cron.NewParser(cron.Minute | cron.Hour | cron.Dom | cron.Month | cron.Dow)
|
|
|
|
|
o.cronParser = &parser
|
|
|
|
|
}
|
|
|
|
|
}
|
2025-10-05 19:21:39 +08:00
|
|
|
|
|
|
|
|
// Cron表达式 符号
|
|
|
|
|
// @yearly @annually => 每年执行一次,等同于 "0 0 0 1 1 *"
|
|
|
|
|
// @monthly => 每月执行一次,等同于 "0 0 0 1 * *"
|
|
|
|
|
// @weekly => 每周执行一次,等同于 "0 0 0 * * 0"
|
|
|
|
|
// @daily @midnight => 每天执行一次,等同于 "0 0 0 * * *"
|
|
|
|
|
// @hourly => 每小时执行一次,等同于 "0 0 * * * *"
|
|
|
|
|
// @minutely => 每分钟执行一次,等同于 "0 * * * * *"
|
|
|
|
|
// @secondly => 每秒执行一次,等同于 "* * * * * *"
|
|
|
|
|
// @every(time.Duration) => 每隔指定时间执行一次,等同于 "@every 5s"
|
|
|
|
|
|
|
|
|
|
func WithCronParserDescriptor() Option {
|
|
|
|
|
return func(o *Options) {
|
|
|
|
|
parser := cron.NewParser(cron.Descriptor)
|
|
|
|
|
o.cronParser = &parser
|
|
|
|
|
}
|
|
|
|
|
}
|