代码拉取完成,页面将自动刷新
// 版权归GoFrame作者(https://goframe.org)所有。保留所有权利。
//
// 本源代码形式受MIT许可证条款约束。
// 如果未随本文件一同分发MIT许可证副本,
// 您可以在https://github.com/gogf/gf处获取。
// md5:a9832f33b234e3f3
package 定时cron类
import (
"context"
"fmt"
"reflect"
"runtime"
"time"
gtype "gitee.com/go_888/goframe/container/gtype"
gcode "gitee.com/go_888/goframe/errors/gcode"
gerror "gitee.com/go_888/goframe/errors/gerror"
glog "gitee.com/go_888/goframe/os/glog"
gtimer "gitee.com/go_888/goframe/os/gtimer"
gconv "gitee.com/go_888/goframe/util/gconv"
)
// X函数类型_JobFunc 是在cron中定时被调用的作业函数。 md5:476072dbc1ca96ff
type X函数类型_JobFunc = gtimer.JobFunc
// X结构_Entry 是定时任务的入口。 md5:ebc0ffec0c819fa5
type X结构_Entry struct {
cron *X结构_定时 // 属于的Cron对象。 md5:b0d31cd3bc86924f
timerEntry *gtimer.X结构_Entry // 相关的定时器条目。 md5:cc0c92f42e2f28c0
schedule *cronSchedule // Timed schedule object.
jobName string // 回调函数名称(地址信息)。 md5:7f130ad66e787420
times *gtype.X结构_整数 // Running times limit.
infinite *gtype.X结构_布尔 // No times limit.
Name string // Entry name.
RegisterTime time.Time // Registered time.
Job X函数类型_JobFunc `json:"-"` // Callback function.
}
type doAddEntryInput struct {
Name string // Name 为手动控制此条目提供名称。 md5:ab6add69f0d6cead
Job X函数类型_JobFunc // Job是定时任务执行的回调函数。 md5:7faad71757692791
Ctx context.Context // 作业的上下文。 md5:505a832c1cca7c0e
Times int // Times 指定了条目的运行限制次数。 md5:bb45eebc85ac5fcc
Pattern string // Pattern 是用于调度的 crontab 风格的字符串。 md5:2076c5de0b0a0288
IsSingleton bool // Singleton 指定是否以单例模式执行定时任务。 md5:f98d6fb605fc538f
Infinite bool // Infinite表示此条目是否无限运行,不受时间限制。 md5:14267dbbffb84b38
}
// doAddEntry 创建并返回一个新的 Entry 对象。 md5:c29537f522377c29
func (c *X结构_定时) doAddEntry(in doAddEntryInput) (*X结构_Entry, error) {
if in.Name != "" {
if c.Search(in.Name) != nil {
return nil, gerror.X创建错误码并格式化(
gcode.X变量_CodeInvalidOperation,
`重复的定时任务名称 "%s",已存在`,
in.Name,
)
}
}
schedule, err := newSchedule(in.Pattern)
if err != nil {
return nil, err
}
// 对于`times`没有限制,用于每秒检查调度的计时器。 md5:dce371ba28b68c21
entry := &X结构_Entry{
cron: c,
schedule: schedule,
jobName: runtime.FuncForPC(reflect.ValueOf(in.Job).Pointer()).Name(),
times: gtype.X创建整数(in.Times),
infinite: gtype.X创建布尔(in.Infinite),
RegisterTime: time.Now(),
Job: in.Job,
}
if in.Name != "" {
entry.Name = in.Name
} else {
entry.Name = "cron-" + gconv.String(c.idGen.X追加(1))
}
// 当你添加一个定时任务时,不能让它立即运行。
// 它在添加到计时器时不能开始执行。
// 应该在将条目添加到Cron条目映射后开始运行,以防止在添加过程中(此时条目信息可能不完整)任务运行,从而可能导致恐慌。
// md5:e2b503aef8166c84
entry.timerEntry = gtimer.X加入详细循环任务(
in.Ctx,
time.Second,
entry.checkAndRun,
in.IsSingleton,
-1,
gtimer.X常量_状态_已停止,
)
c.entries.X设置值(entry.Name, entry)
entry.timerEntry.X开始工作()
return entry, nil
}
// IsSingleton 判断这个条目是否是定时单例任务。 md5:171967c731b60f88
func (e *X结构_Entry) IsSingleton() bool {
return e.timerEntry.X是否单例模式()
}
// SetSingleton 设置以单例模式运行的条目。 md5:6c81a3a09d0ef0b1
func (e *X结构_Entry) SetSingleton(enabled bool) {
e.timerEntry.X设置单例模式(enabled)
}
// SetTimes 设置条目可以运行的时间。 md5:663af054d5aab5e9
func (e *X结构_Entry) SetTimes(times int) {
e.times.X设置值(times)
e.infinite.X设置值(false)
}
// Status 返回条目的状态。 md5:6a9d3438dc575881
func (e *X结构_Entry) Status() int {
return e.timerEntry.X取任务状态()
}
// SetStatus 设置条目的状态。 md5:ea0ecb4171f3f017
func (e *X结构_Entry) SetStatus(status int) int {
return e.timerEntry.X设置任务状态(status)
}
// Start 开始运行入口函数。 md5:aa729d73eb626ca1
func (e *X结构_Entry) Start() {
e.timerEntry.X开始工作()
}
// Stop 停止运行条目。 md5:06d53148d6536ce9
func (e *X结构_Entry) Stop() {
e.timerEntry.X暂停工作()
}
// Close 停止并从 cron 中移除条目。 md5:a2a5eee9228cd918
func (e *X结构_Entry) Close() {
e.cron.entries.X删除(e.Name)
e.timerEntry.X关闭任务()
}
// checkAndRun是核心定时任务检查逻辑。
// 这个函数每秒被调用一次。
// md5:e4a94345d01fd7df
func (e *X结构_Entry) checkAndRun(ctx context.Context) {
currentTime := time.Now()
if !e.schedule.checkMeetAndUpdateLastSeconds(ctx, currentTime) {
return
}
switch e.cron.status.X取值() {
case X常量_StatusStopped:
return
case X常量_StatusClosed:
e.logDebugf(ctx, `定时任务 "%s" 已移除`, e.getJobNameWithPattern())
e.Close()
case X常量_StatusReady, X常量_StatusRunning:
defer func() {
if exception := recover(); exception != nil {
// 捕获到异常,默认行为是将错误内容记录到日志中。 md5:9af43ee64f5795bf
e.logErrorf(ctx,
`定时任务 "%s(%s)" 结束时出错: %+v`,
e.jobName, e.schedule.pattern, exception,
)
} else {
e.logDebugf(ctx, `定时任务 "%s" 结束`, e.getJobNameWithPattern())
}
if e.timerEntry.X取任务状态() == X常量_StatusClosed {
e.Close()
}
}()
// Running times check.
if !e.infinite.X取值() {
times := e.times.X追加(-1)
if times <= 0 {
if e.timerEntry.X设置任务状态(X常量_StatusClosed) == X常量_StatusClosed || times < 0 {
return
}
}
}
e.logDebugf(ctx, `定时任务 "%s" 开始`, e.getJobNameWithPattern())
e.Job(ctx)
}
}
func (e *X结构_Entry) getJobNameWithPattern() string {
return fmt.Sprintf(`%s(%s)`, e.jobName, e.schedule.pattern)
}
func (e *X结构_Entry) logDebugf(ctx context.Context, format string, v ...interface{}) {
if logger := e.cron.GetLogger(); logger != nil {
logger.X输出并格式化DEBU(ctx, format, v...)
}
}
func (e *X结构_Entry) logErrorf(ctx context.Context, format string, v ...interface{}) {
logger := e.cron.GetLogger()
if logger == nil {
logger = glog.X取默认日志类()
}
logger.X输出并格式化ERR(ctx, format, v...)
}
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。