fix bugs; move to gocron for scheduled jobs
This commit is contained in:
74
internal/utils/scheduler.go
Normal file
74
internal/utils/scheduler.go
Normal file
@@ -0,0 +1,74 @@
|
||||
package utils
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"github.com/go-co-op/gocron/v2"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
)
|
||||
|
||||
func ScheduleJob(ctx context.Context, interval string, loc *time.Location, jobFunc func()) (gocron.Job, error) {
|
||||
if loc == nil {
|
||||
loc = time.Local
|
||||
}
|
||||
var job gocron.Job
|
||||
s, err := gocron.NewScheduler(gocron.WithLocation(loc))
|
||||
if err != nil {
|
||||
return job, fmt.Errorf("failed to create scheduler: %w", err)
|
||||
}
|
||||
jd, err := convertToJD(interval)
|
||||
if err != nil {
|
||||
return job, fmt.Errorf("failed to convert interval to job definition: %w", err)
|
||||
}
|
||||
// Schedule the job
|
||||
if job, err = s.NewJob(jd, gocron.NewTask(jobFunc), gocron.WithContext(ctx)); err != nil {
|
||||
return job, fmt.Errorf("failed to create job: %w", err)
|
||||
}
|
||||
s.Start()
|
||||
return job, nil
|
||||
}
|
||||
|
||||
// ConvertToJobDef converts a string interval to a gocron.JobDefinition.
|
||||
func convertToJD(interval string) (gocron.JobDefinition, error) {
|
||||
// Parse the interval string
|
||||
// Interval could be in the format "1h", "30m", "15s" or "1h30m" or "04:05"
|
||||
var jd gocron.JobDefinition
|
||||
|
||||
if t, ok := parseClockTime(interval); ok {
|
||||
return gocron.DailyJob(1, gocron.NewAtTimes(
|
||||
gocron.NewAtTime(uint(t.Hour()), uint(t.Minute()), uint(t.Second())),
|
||||
)), nil
|
||||
} else {
|
||||
dur, err := time.ParseDuration(interval)
|
||||
if err != nil {
|
||||
return jd, fmt.Errorf("failed to parse duration: %w", err)
|
||||
}
|
||||
jd = gocron.DurationJob(dur)
|
||||
}
|
||||
return jd, nil
|
||||
}
|
||||
|
||||
func parseClockTime(s string) (time.Time, bool) {
|
||||
parts := strings.Split(s, ":")
|
||||
if len(parts) != 2 {
|
||||
return time.Time{}, false
|
||||
}
|
||||
h, err := strconv.Atoi(parts[0])
|
||||
if err != nil || h < 0 || h > 23 {
|
||||
return time.Time{}, false
|
||||
}
|
||||
m, err := strconv.Atoi(parts[1])
|
||||
if err != nil || m < 0 || m > 59 {
|
||||
return time.Time{}, false
|
||||
}
|
||||
now := time.Now()
|
||||
// build a time.Time for today at h:m:00 in the local zone
|
||||
t := time.Date(
|
||||
now.Year(), now.Month(), now.Day(),
|
||||
h, m, 0, 0,
|
||||
time.Local,
|
||||
)
|
||||
return t, true
|
||||
}
|
||||
Reference in New Issue
Block a user