Use global lock instead of status pool for cron lock (#35507)

This commit is contained in:
Lunny Xiao
2025-09-27 10:11:52 -07:00
committed by GitHub
parent 1f32170060
commit 8106d95577
5 changed files with 18 additions and 99 deletions
+2 -6
View File
@@ -11,7 +11,6 @@ import (
"code.gitea.io/gitea/modules/graceful"
"code.gitea.io/gitea/modules/process"
"code.gitea.io/gitea/modules/sync"
"code.gitea.io/gitea/modules/translation"
"github.com/go-co-op/gocron"
@@ -19,13 +18,10 @@ import (
var scheduler = gocron.NewScheduler(time.Local)
// Prevent duplicate running tasks.
var taskStatusTable = sync.NewStatusTable()
// NewContext begins cron tasks
// Init begins cron tasks
// Each cron task is run within the shutdown context as a running server
// AtShutdown the cron server is stopped
func NewContext(original context.Context) {
func Init(original context.Context) {
defer pprof.SetGoroutineLabels(original)
_, _, finished := process.GetManager().AddTypedContext(graceful.GetManager().ShutdownContext(), "Service: Cron", process.SystemProcessType, true)
initBasicTasks()
+15 -4
View File
@@ -14,6 +14,7 @@ import (
"code.gitea.io/gitea/models/db"
system_model "code.gitea.io/gitea/models/system"
user_model "code.gitea.io/gitea/models/user"
"code.gitea.io/gitea/modules/globallock"
"code.gitea.io/gitea/modules/graceful"
"code.gitea.io/gitea/modules/log"
"code.gitea.io/gitea/modules/process"
@@ -71,20 +72,30 @@ func (t *Task) Run() {
}, t.config)
}
func getCronTaskLockKey(name string) string {
return "cron_task:" + name
}
// RunWithUser will run the task incrementing the cron counter at the time with User
func (t *Task) RunWithUser(doer *user_model.User, config Config) {
if !taskStatusTable.StartIfNotRunning(t.Name) {
locked, releaser, err := globallock.TryLock(graceful.GetManager().ShutdownContext(), getCronTaskLockKey(t.Name))
if err != nil {
log.Error("Failed to acquire lock for cron task %q: %v", t.Name, err)
return
}
if !locked {
log.Trace("a cron task %q is already running", t.Name)
return
}
defer releaser()
t.lock.Lock()
if config == nil {
config = t.config
}
t.ExecTimes++
t.lock.Unlock()
defer func() {
taskStatusTable.Stop(t.Name)
}()
graceful.GetManager().RunWithShutdownContext(func(baseCtx context.Context) {
defer func() {
if err := recover(); err != nil {