初始提交: Gitea 项目代码
This commit is contained in:
@@ -0,0 +1,137 @@
|
||||
// Copyright 2014 The Gogs Authors. All rights reserved.
|
||||
// Copyright 2019 The Gitea Authors. All rights reserved.
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
package cron
|
||||
|
||||
import (
|
||||
"context"
|
||||
"runtime/pprof"
|
||||
"time"
|
||||
|
||||
"gitea.dev/modules/graceful"
|
||||
"gitea.dev/modules/log"
|
||||
"gitea.dev/modules/process"
|
||||
"gitea.dev/modules/translation"
|
||||
|
||||
"github.com/go-co-op/gocron/v2"
|
||||
)
|
||||
|
||||
var scheduler gocron.Scheduler
|
||||
|
||||
func init() {
|
||||
var err error
|
||||
scheduler, err = gocron.NewScheduler(gocron.WithLocation(time.Local))
|
||||
if err != nil {
|
||||
log.Fatal("Unable to create cron scheduler: %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
// Init begins cron tasks
|
||||
// Each cron task is run within the shutdown context as a running server
|
||||
// AtShutdown the cron server is stopped
|
||||
func Init(original context.Context) {
|
||||
defer pprof.SetGoroutineLabels(original)
|
||||
_, _, finished := process.GetManager().AddTypedContext(graceful.GetManager().ShutdownContext(), "Service: Cron", process.SystemProcessType, true)
|
||||
initBasicTasks()
|
||||
initExtendedTasks()
|
||||
initActionsTasks()
|
||||
|
||||
lock.Lock()
|
||||
for _, task := range tasks {
|
||||
if task.IsEnabled() && task.DoRunAtStart() {
|
||||
go task.Run()
|
||||
}
|
||||
}
|
||||
|
||||
scheduler.Start()
|
||||
started = true
|
||||
lock.Unlock()
|
||||
graceful.GetManager().RunAtShutdown(context.Background(), func() {
|
||||
if err := scheduler.Shutdown(); err != nil {
|
||||
log.Error("Unable to shutdown cron scheduler: %v", err)
|
||||
}
|
||||
lock.Lock()
|
||||
started = false
|
||||
lock.Unlock()
|
||||
finished()
|
||||
})
|
||||
}
|
||||
|
||||
// TaskTableRow represents a task row in the tasks table
|
||||
type TaskTableRow struct {
|
||||
Name string
|
||||
Spec string
|
||||
Next time.Time
|
||||
Prev time.Time
|
||||
Status string
|
||||
LastMessage string
|
||||
LastDoer string
|
||||
ExecTimes int64
|
||||
task *Task
|
||||
}
|
||||
|
||||
func (t *TaskTableRow) FormatLastMessage(locale translation.Locale) string {
|
||||
if t.Status == "finished" {
|
||||
return t.task.GetConfig().FormatMessage(locale, t.Name, t.Status, t.LastDoer)
|
||||
}
|
||||
|
||||
return t.task.GetConfig().FormatMessage(locale, t.Name, t.Status, t.LastDoer, t.LastMessage)
|
||||
}
|
||||
|
||||
// TaskTable represents a table of tasks
|
||||
type TaskTable []*TaskTableRow
|
||||
|
||||
// ListTasks returns all running cron tasks.
|
||||
func ListTasks() TaskTable {
|
||||
jobs := scheduler.Jobs()
|
||||
jobMap := map[string]gocron.Job{}
|
||||
for _, job := range jobs {
|
||||
// the first tag is the task name
|
||||
tags := job.Tags()
|
||||
if len(tags) == 0 { // should never happen
|
||||
continue
|
||||
}
|
||||
jobMap[tags[0]] = job
|
||||
}
|
||||
|
||||
lock.Lock()
|
||||
defer lock.Unlock()
|
||||
|
||||
tTable := make([]*TaskTableRow, 0, len(tasks))
|
||||
for _, task := range tasks {
|
||||
spec := "-"
|
||||
var (
|
||||
next time.Time
|
||||
prev time.Time
|
||||
)
|
||||
if e, ok := jobMap[task.Name]; ok {
|
||||
tags := e.Tags()
|
||||
if len(tags) > 1 {
|
||||
spec = tags[1] // the second tag is the task spec
|
||||
}
|
||||
next, _ = e.NextRun()
|
||||
prev, _ = e.LastRunStartedAt()
|
||||
}
|
||||
|
||||
task.lock.Lock()
|
||||
// If the manual run is after the cron run, use that instead.
|
||||
if prev.Before(task.LastRun) {
|
||||
prev = task.LastRun
|
||||
}
|
||||
tTable = append(tTable, &TaskTableRow{
|
||||
Name: task.Name,
|
||||
Spec: spec,
|
||||
Next: next,
|
||||
Prev: prev,
|
||||
ExecTimes: task.ExecTimes,
|
||||
LastMessage: task.LastMessage,
|
||||
Status: task.Status,
|
||||
LastDoer: task.LastDoer,
|
||||
task: task,
|
||||
})
|
||||
task.lock.Unlock()
|
||||
}
|
||||
|
||||
return tTable
|
||||
}
|
||||
Reference in New Issue
Block a user