go-co-op / gocron

Easy and fluent Go cron scheduling. This is a fork from https://github.com/jasonlvhit/gocron
MIT License
5.68k stars 309 forks source link

[BUG] - DailyJob and OneTimeJob get overwritten by each other #790

Closed juzeon closed 3 weeks ago

juzeon commented 3 weeks ago

Describe the bug

When adding a daily job and a one time job, they seem to be overwritten by each other. Please check the PoC below.

To Reproduce

package main

import (
    "github.com/go-co-op/gocron/v2"
    "log/slog"
    "time"
)

func main() {
    scheduler, err := gocron.NewScheduler()
    if err != nil {
        panic(err)
    }

    dailyJob, err := scheduler.NewJob(
        gocron.DailyJob(0, gocron.NewAtTimes(gocron.NewAtTime(0, 0, 1))),
        gocron.NewTask(func() {
            slog.Info("Scheduling for a new day", "current", time.Now())
        }),
    )
    if err != nil {
        panic(err)
    }

    timeNow := time.Now()
    startTime := time.Date(timeNow.Year(), timeNow.Month(), timeNow.Day(), timeNow.Hour(), timeNow.Minute()+2,
        0, 0, time.Local)
    oneTimeJob, err := scheduler.NewJob(gocron.OneTimeJob(gocron.OneTimeJobStartDateTime(startTime)),
        gocron.NewTask(func() {
            slog.Info("Run")
        }),
    )
    if err != nil {
        panic(err)
    }
    scheduler.Start()
    for {
        r, err := dailyJob.NextRun()
        slog.Info("Daily", "nextRun", r, "err", err)
        r, err = oneTimeJob.NextRun()
        slog.Info("OneTime", "nextRun", r, "err", err)
        time.Sleep(1 * time.Second)
    }
}

Output:

2024/10/31 11:18:45 INFO Daily nextRun=2024-10-31T00:00:01.288+08:00 err=<nil>
2024/10/31 11:18:45 INFO OneTime nextRun=2024-10-31T11:20:00.000+08:00 err=<nil>
2024/10/31 11:18:47 INFO Daily nextRun=0001-01-01T00:00:00.000Z err="gocron: job not found"
2024/10/31 11:18:48 INFO OneTime nextRun=0001-01-01T00:00:00.000Z err="gocron: job not found"
2024/10/31 11:18:50 INFO Daily nextRun=0001-01-01T00:00:00.000Z err="gocron: job not found"
2024/10/31 11:18:51 INFO OneTime nextRun=0001-01-01T00:00:00.000Z err="gocron: job not found"
2024/10/31 11:18:53 INFO Daily nextRun=0001-01-01T00:00:00.000Z err="gocron: job not found"
2024/10/31 11:18:54 INFO OneTime nextRun=0001-01-01T00:00:00.000Z err="gocron: job not found"
2024/10/31 11:18:56 INFO Daily nextRun=0001-01-01T00:00:00.000Z err="gocron: job not found"
2024/10/31 11:18:57 INFO OneTime nextRun=0001-01-01T00:00:00.000Z err="gocron: job not found"
2024/10/31 11:18:59 INFO Daily nextRun=0001-01-01T00:00:00.000Z err="gocron: job not found"
2024/10/31 11:19:00 INFO OneTime nextRun=0001-01-01T00:00:00.000Z err="gocron: job not found"
2024/10/31 11:19:02 INFO Daily nextRun=0001-01-01T00:00:00.000Z err="gocron: job not found"
2024/10/31 11:19:03 INFO OneTime nextRun=0001-01-01T00:00:00.000Z err="gocron: job not found"

Version

Go: 1.23.1

gocron: v2.12.1

Expected behavior

Jobs should not getting not found.

Additional context

I noticed if I change the line:

dailyJob, err := scheduler.NewJob(
-       gocron.DailyJob(0, gocron.NewAtTimes(gocron.NewAtTime(0, 0, 1))),
+      gocron.DailyJob(1, gocron.NewAtTimes(gocron.NewAtTime(0, 0, 1))),
        gocron.NewTask(func() {
            slog.Info("Scheduling for a new day", "current", time.Now())
        }),
    )

Then I would get it worked expectedly:

2024/10/31 11:28:45 INFO Daily nextRun=2024-11-01T00:00:01.196+08:00 err=<nil>
2024/10/31 11:28:45 INFO OneTime nextRun=2024-10-31T11:30:00.000+08:00 err=<nil>
2024/10/31 11:28:46 INFO Daily nextRun=2024-11-01T00:00:01.196+08:00 err=<nil>
2024/10/31 11:28:46 INFO OneTime nextRun=2024-10-31T11:30:00.000+08:00 err=<nil>
2024/10/31 11:28:47 INFO Daily nextRun=2024-11-01T00:00:01.196+08:00 err=<nil>
2024/10/31 11:28:47 INFO OneTime nextRun=2024-10-31T11:30:00.000+08:00 err=<nil>

Is this an expected behavior?

Thanks in advance.

JohnRoesler commented 3 weeks ago

@juzeon thanks for calling this out. That's a data validation bug. An interval of zero should not be allowed.

juzeon commented 3 weeks ago

Thanks for your hard working!