mirror of
				https://gitee.com/dromara/mayfly-go
				synced 2025-11-04 08:20:25 +08:00 
			
		
		
		
	
		
			
	
	
		
			236 lines
		
	
	
		
			4.9 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
		
		
			
		
	
	
			236 lines
		
	
	
		
			4.9 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
| 
								 | 
							
								package entity
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								import (
							 | 
						||
| 
								 | 
							
									"context"
							 | 
						||
| 
								 | 
							
									"fmt"
							 | 
						||
| 
								 | 
							
									"mayfly-go/pkg/model"
							 | 
						||
| 
								 | 
							
									"mayfly-go/pkg/runner"
							 | 
						||
| 
								 | 
							
									"mayfly-go/pkg/utils/stringx"
							 | 
						||
| 
								 | 
							
									"mayfly-go/pkg/utils/timex"
							 | 
						||
| 
								 | 
							
									"time"
							 | 
						||
| 
								 | 
							
								)
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								const LastResultSize = 256
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								type DbJobKey = runner.JobKey
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								type DbJobStatus = runner.JobStatus
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								const (
							 | 
						||
| 
								 | 
							
									DbJobUnknown = runner.JobUnknown
							 | 
						||
| 
								 | 
							
									DbJobDelay   = runner.JobDelay
							 | 
						||
| 
								 | 
							
									DbJobReady   = runner.JobWaiting
							 | 
						||
| 
								 | 
							
									DbJobRunning = runner.JobRunning
							 | 
						||
| 
								 | 
							
									DbJobRemoved = runner.JobRemoved
							 | 
						||
| 
								 | 
							
								)
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								const (
							 | 
						||
| 
								 | 
							
									DbJobSuccess DbJobStatus = 0x20 + iota
							 | 
						||
| 
								 | 
							
									DbJobFailed
							 | 
						||
| 
								 | 
							
								)
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								type DbJobType = string
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								const (
							 | 
						||
| 
								 | 
							
									DbJobTypeBackup  DbJobType = "db-backup"
							 | 
						||
| 
								 | 
							
									DbJobTypeRestore DbJobType = "db-restore"
							 | 
						||
| 
								 | 
							
								)
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								const (
							 | 
						||
| 
								 | 
							
									DbJobNameBackup  = "数据库备份"
							 | 
						||
| 
								 | 
							
									DbJobNameRestore = "数据库恢复"
							 | 
						||
| 
								 | 
							
								)
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								var _ runner.Job = (DbJob)(nil)
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								type DbJobBase interface {
							 | 
						||
| 
								 | 
							
									model.ModelI
							 | 
						||
| 
								 | 
							
									runner.Job
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									GetId() uint64
							 | 
						||
| 
								 | 
							
									GetJobType() DbJobType
							 | 
						||
| 
								 | 
							
									SetJobType(typ DbJobType)
							 | 
						||
| 
								 | 
							
									GetJobBase() *DbJobBaseImpl
							 | 
						||
| 
								 | 
							
									SetLastStatus(status DbJobStatus, err error)
							 | 
						||
| 
								 | 
							
									IsEnabled() bool
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								type DbJob interface {
							 | 
						||
| 
								 | 
							
									DbJobBase
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									SetRun(fn func(ctx context.Context, job DbJob))
							 | 
						||
| 
								 | 
							
									SetRunnable(fn func(job DbJob, next runner.NextFunc) bool)
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								func NewDbJob(typ DbJobType) DbJob {
							 | 
						||
| 
								 | 
							
									switch typ {
							 | 
						||
| 
								 | 
							
									case DbJobTypeBackup:
							 | 
						||
| 
								 | 
							
										return &DbBackup{
							 | 
						||
| 
								 | 
							
											DbJobBaseImpl: &DbJobBaseImpl{
							 | 
						||
| 
								 | 
							
												jobType: DbJobTypeBackup},
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
									case DbJobTypeRestore:
							 | 
						||
| 
								 | 
							
										return &DbRestore{
							 | 
						||
| 
								 | 
							
											DbJobBaseImpl: &DbJobBaseImpl{
							 | 
						||
| 
								 | 
							
												jobType: DbJobTypeRestore},
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
									default:
							 | 
						||
| 
								 | 
							
										panic(fmt.Sprintf("invalid DbJobType: %v", typ))
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								var _ DbJobBase = (*DbJobBaseImpl)(nil)
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								type DbJobBaseImpl struct {
							 | 
						||
| 
								 | 
							
									model.Model
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									DbInstanceId uint64         // 数据库实例ID
							 | 
						||
| 
								 | 
							
									DbName       string         // 数据库名称
							 | 
						||
| 
								 | 
							
									Enabled      bool           // 是否启用
							 | 
						||
| 
								 | 
							
									StartTime    time.Time      // 开始时间
							 | 
						||
| 
								 | 
							
									Interval     time.Duration  // 间隔时间
							 | 
						||
| 
								 | 
							
									Repeated     bool           // 是否重复执行
							 | 
						||
| 
								 | 
							
									LastStatus   DbJobStatus    // 最近一次执行状态
							 | 
						||
| 
								 | 
							
									LastResult   string         // 最近一次执行结果
							 | 
						||
| 
								 | 
							
									LastTime     timex.NullTime // 最近一次执行时间
							 | 
						||
| 
								 | 
							
									Deadline     time.Time      `gorm:"-" json:"-"` // 计划执行时间
							 | 
						||
| 
								 | 
							
									run          runner.RunFunc
							 | 
						||
| 
								 | 
							
									runnable     runner.RunnableFunc
							 | 
						||
| 
								 | 
							
									jobType      DbJobType
							 | 
						||
| 
								 | 
							
									jobKey       runner.JobKey
							 | 
						||
| 
								 | 
							
									jobStatus    runner.JobStatus
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								func NewDbBJobBase(instanceId uint64, dbName string, jobType DbJobType, enabled bool, repeated bool, startTime time.Time, interval time.Duration) *DbJobBaseImpl {
							 | 
						||
| 
								 | 
							
									return &DbJobBaseImpl{
							 | 
						||
| 
								 | 
							
										DbInstanceId: instanceId,
							 | 
						||
| 
								 | 
							
										DbName:       dbName,
							 | 
						||
| 
								 | 
							
										jobType:      jobType,
							 | 
						||
| 
								 | 
							
										Enabled:      enabled,
							 | 
						||
| 
								 | 
							
										Repeated:     repeated,
							 | 
						||
| 
								 | 
							
										StartTime:    startTime,
							 | 
						||
| 
								 | 
							
										Interval:     interval,
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								func (d *DbJobBaseImpl) GetJobType() DbJobType {
							 | 
						||
| 
								 | 
							
									return d.jobType
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								func (d *DbJobBaseImpl) SetJobType(typ DbJobType) {
							 | 
						||
| 
								 | 
							
									d.jobType = typ
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								func (d *DbJobBaseImpl) SetLastStatus(status DbJobStatus, err error) {
							 | 
						||
| 
								 | 
							
									var statusName, jobName string
							 | 
						||
| 
								 | 
							
									switch status {
							 | 
						||
| 
								 | 
							
									case DbJobRunning:
							 | 
						||
| 
								 | 
							
										statusName = "运行中"
							 | 
						||
| 
								 | 
							
									case DbJobSuccess:
							 | 
						||
| 
								 | 
							
										statusName = "成功"
							 | 
						||
| 
								 | 
							
									case DbJobFailed:
							 | 
						||
| 
								 | 
							
										statusName = "失败"
							 | 
						||
| 
								 | 
							
									default:
							 | 
						||
| 
								 | 
							
										return
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
									switch d.jobType {
							 | 
						||
| 
								 | 
							
									case DbJobTypeBackup:
							 | 
						||
| 
								 | 
							
										jobName = DbJobNameBackup
							 | 
						||
| 
								 | 
							
									case DbJobTypeRestore:
							 | 
						||
| 
								 | 
							
										jobName = DbJobNameRestore
							 | 
						||
| 
								 | 
							
									default:
							 | 
						||
| 
								 | 
							
										jobName = d.jobType
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
									d.LastStatus = status
							 | 
						||
| 
								 | 
							
									var result = jobName + statusName
							 | 
						||
| 
								 | 
							
									if err != nil {
							 | 
						||
| 
								 | 
							
										result = fmt.Sprintf("%s: %v", result, err)
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
									d.LastResult = stringx.TruncateStr(result, LastResultSize)
							 | 
						||
| 
								 | 
							
									d.LastTime = timex.NewNullTime(time.Now())
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								func (d *DbJobBaseImpl) GetId() uint64 {
							 | 
						||
| 
								 | 
							
									if d == nil {
							 | 
						||
| 
								 | 
							
										return 0
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
									return d.Id
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								func (d *DbJobBaseImpl) GetDeadline() time.Time {
							 | 
						||
| 
								 | 
							
									return d.Deadline
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								func (d *DbJobBaseImpl) Schedule() bool {
							 | 
						||
| 
								 | 
							
									if d.IsFinished() || !d.Enabled {
							 | 
						||
| 
								 | 
							
										return false
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
									switch d.LastStatus {
							 | 
						||
| 
								 | 
							
									case DbJobSuccess:
							 | 
						||
| 
								 | 
							
										if d.Interval == 0 {
							 | 
						||
| 
								 | 
							
											return false
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
										lastTime := d.LastTime.Time
							 | 
						||
| 
								 | 
							
										if lastTime.Sub(d.StartTime) < 0 {
							 | 
						||
| 
								 | 
							
											lastTime = d.StartTime.Add(-d.Interval)
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
										d.Deadline = lastTime.Add(d.Interval - lastTime.Sub(d.StartTime)%d.Interval)
							 | 
						||
| 
								 | 
							
									case DbJobFailed:
							 | 
						||
| 
								 | 
							
										d.Deadline = time.Now().Add(time.Minute)
							 | 
						||
| 
								 | 
							
									default:
							 | 
						||
| 
								 | 
							
										d.Deadline = d.StartTime
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
									return true
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								func (d *DbJobBaseImpl) IsFinished() bool {
							 | 
						||
| 
								 | 
							
									return !d.Repeated && d.LastStatus == DbJobSuccess
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								func (d *DbJobBaseImpl) Renew(job runner.Job) {
							 | 
						||
| 
								 | 
							
									jobBase := job.(DbJob).GetJobBase()
							 | 
						||
| 
								 | 
							
									d.StartTime = jobBase.StartTime
							 | 
						||
| 
								 | 
							
									d.Interval = jobBase.Interval
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								func (d *DbJobBaseImpl) GetJobBase() *DbJobBaseImpl {
							 | 
						||
| 
								 | 
							
									return d
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								func (d *DbJobBaseImpl) IsEnabled() bool {
							 | 
						||
| 
								 | 
							
									return d.Enabled
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								func (d *DbJobBaseImpl) Run(ctx context.Context) {
							 | 
						||
| 
								 | 
							
									if d.run == nil {
							 | 
						||
| 
								 | 
							
										return
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
									d.run(ctx)
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								func (d *DbJobBaseImpl) Runnable(next runner.NextFunc) bool {
							 | 
						||
| 
								 | 
							
									if d.runnable == nil {
							 | 
						||
| 
								 | 
							
										return true
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
									return d.runnable(next)
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								func FormatJobKey(typ DbJobType, jobId uint64) DbJobKey {
							 | 
						||
| 
								 | 
							
									return fmt.Sprintf("%v-%d", typ, jobId)
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								func (d *DbJobBaseImpl) GetKey() DbJobKey {
							 | 
						||
| 
								 | 
							
									if len(d.jobKey) == 0 {
							 | 
						||
| 
								 | 
							
										d.jobKey = FormatJobKey(d.jobType, d.Id)
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
									return d.jobKey
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								func (d *DbJobBaseImpl) GetStatus() DbJobStatus {
							 | 
						||
| 
								 | 
							
									return d.jobStatus
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								func (d *DbJobBaseImpl) SetStatus(status DbJobStatus) {
							 | 
						||
| 
								 | 
							
									d.jobStatus = status
							 | 
						||
| 
								 | 
							
								}
							 |