subsyt/internal/scheduler/scheduler.go
Viktor Varland f1195adc5c
All checks were successful
build / build (push) Successful in 1m22s
fix: add missing package
2025-04-14 12:39:35 +02:00

90 lines
1.8 KiB
Go

package scheduler
import (
"log"
"reflect"
"runtime"
"time"
)
type Job struct {
interval time.Duration
funcname string
function interface{}
params []interface{}
lastRun time.Time
nextRun time.Time
atTime time.Duration
}
type Scheduler struct {
}
func (j *Job) run() ([]reflect.Value, bool) {
f := reflect.ValueOf(j.function)
if len(j.params) != f.Type().NumIn() {
return nil, false
}
in := make([]reflect.Value, len(j.params))
for k, param := range j.params {
in[k] = reflect.ValueOf(param)
}
return f.Call(in), true
}
func (*Scheduler) Start(fn interface{}, params ...interface{}) {
ticker := time.NewTicker(time.Second)
defer ticker.Stop()
done := make(chan bool)
f := runtime.FuncForPC(reflect.ValueOf(fn).Pointer()).Name()
job := Job{
interval: time.Duration(1 * time.Hour * 24),
funcname: f,
function: fn,
params: params,
lastRun: time.Unix(0, 0),
nextRun: time.Unix(0, 0),
atTime: time.Duration(4)*time.Hour + time.Duration(0)*time.Minute + time.Duration(0)*time.Second,
}
log.Println(job)
if job.lastRun == time.Unix(0, 0) {
job.lastRun = time.Now()
}
go func() {
time.Sleep(60 * time.Second)
}()
for {
select {
case <-done:
log.Println("done !")
return
case <-ticker.C:
if time.Now().Unix() >= job.nextRun.Unix() {
j, ok := job.run()
if !ok {
log.Println("failed")
}
log.Println("job ran", j)
now := time.Now()
job.lastRun = now
job.nextRun = time.Date(job.lastRun.Year(), job.lastRun.Month(), job.lastRun.Day(), 0, 0, 0, 0, time.UTC)
job.nextRun = job.nextRun.Add(job.atTime)
for job.nextRun.Before(now) || job.nextRun.Before(job.lastRun) {
job.nextRun = job.nextRun.Add(job.interval)
}
log.Printf("next run at %s", job.nextRun)
}
}
}
}