mirror of
https://github.com/Rain-kl/OpenFlare.git
synced 2026-10-08 16:46:37 +08:00
migrate
This commit is contained in:
@@ -0,0 +1,97 @@
|
||||
// Copyright 2026 Arctel.net
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
package tasks
|
||||
|
||||
import (
|
||||
"context"
|
||||
"sync"
|
||||
|
||||
"github.com/Rain-kl/Wavelet/pkg/logger"
|
||||
"github.com/robfig/cron/v3"
|
||||
)
|
||||
|
||||
type cronJob struct {
|
||||
name string
|
||||
spec string
|
||||
run func(context.Context)
|
||||
}
|
||||
|
||||
var (
|
||||
registryMu sync.Mutex
|
||||
started bool
|
||||
cronJobs []cronJob
|
||||
cronRunner *cron.Cron
|
||||
jobCtx context.Context
|
||||
jobCancel context.CancelFunc
|
||||
)
|
||||
|
||||
func registerJob(name, cronSpec string, fn func(context.Context)) {
|
||||
registryMu.Lock()
|
||||
defer registryMu.Unlock()
|
||||
cronJobs = append(cronJobs, cronJob{name: name, spec: cronSpec, run: fn})
|
||||
}
|
||||
|
||||
// RegisterCronJob registers a cron job from another OpenFlare package (for example waf).
|
||||
// Prefer registerJob from init() inside this package when possible.
|
||||
func RegisterCronJob(name, cronSpec string, fn func(context.Context)) {
|
||||
registerJob(name, cronSpec, fn)
|
||||
}
|
||||
|
||||
// LogJobError records a failed OpenFlare cron job run.
|
||||
func LogJobError(ctx context.Context, name string, err error) {
|
||||
logger.ErrorF(ctx, "[OpenFlareTasks] %s failed: %v", name, err)
|
||||
}
|
||||
|
||||
// Start launches the cron scheduler in a background goroutine. Safe to call multiple times.
|
||||
func Start(ctx context.Context) {
|
||||
registryMu.Lock()
|
||||
defer registryMu.Unlock()
|
||||
if started {
|
||||
return
|
||||
}
|
||||
|
||||
jobCtx, jobCancel = context.WithCancel(context.Background())
|
||||
runner := cron.New()
|
||||
for _, job := range cronJobs {
|
||||
current := job
|
||||
if _, err := runner.AddFunc(current.spec, func() {
|
||||
current.run(jobCtx)
|
||||
}); err != nil {
|
||||
logger.ErrorF(ctx, "[OpenFlareTasks] register cron job %q failed: %v", current.name, err)
|
||||
continue
|
||||
}
|
||||
logger.InfoF(ctx, "[OpenFlareTasks] registered cron job %q (%s)", current.name, current.spec)
|
||||
}
|
||||
runner.Start()
|
||||
cronRunner = runner
|
||||
started = true
|
||||
}
|
||||
|
||||
// Stop shuts down the cron scheduler gracefully and cancels job contexts.
|
||||
func Stop() {
|
||||
registryMu.Lock()
|
||||
defer registryMu.Unlock()
|
||||
if !started || cronRunner == nil {
|
||||
return
|
||||
}
|
||||
|
||||
stopCtx := cronRunner.Stop()
|
||||
<-stopCtx.Done()
|
||||
if jobCancel != nil {
|
||||
jobCancel()
|
||||
}
|
||||
|
||||
cronRunner = nil
|
||||
started = false
|
||||
jobCtx = nil
|
||||
jobCancel = nil
|
||||
}
|
||||
|
||||
// ResetRegistryForTest clears scheduler state so unit tests can call Start again.
|
||||
func ResetRegistryForTest() {
|
||||
Stop()
|
||||
registryMu.Lock()
|
||||
defer registryMu.Unlock()
|
||||
cronJobs = nil
|
||||
}
|
||||
Reference in New Issue
Block a user