Monday, January 29, 2024

[SOLVED] Standard library implementation (testable) of gocron function

Issue

I have a requirement to run a job (hitting rest endpoint, then sending message to queue) on a timed interval. Currently I have this function, which using gocron - href="https://github.com/go-co-op/gocron" rel="nofollow noreferrer">https://github.com/go-co-op/gocron

However currently there is no mechanism for stopping the function, and therefore no way I can test it cleanly.

func RunSchedule(cronExpression string, myFunction func()) error {
    scheduler := gocron.NewScheduler(time.UTC)
    _, err := scheduler.Cron(cronExpression).StartImmediately().Do(myFunction)
    if err != nil {
        return err
    }
    scheduler.StartBlocking()
    return nil
}

It executes as required and runs the parameterized function at the desired interval but I'm sure there must be a cleaner solution - probably the standard library.


Solution

You could just return the .Stop function:

func RunSchedule(cronExpression string, myFunction func()) (stop func(), err error) {
    scheduler := gocron.NewScheduler(time.UTC)
    _, err = scheduler.Cron(cronExpression).StartImmediately().Do(myFunction)
    if err != nil {
        return nil, err
    }
    go func() {
        scheduler.StartBlocking()
    }()

    return scheduler.Stop, nil
}

and then in your test you could do something like:

called := 0
stop, err := RunSchedule("some-schedule", func() {
    called++
})
time.Sleep(time.Second * 1) // whatever you need to do 
stop()
if called != 1 {
    t.Fail("called should be 1")
}


Answered By - dave
Answer Checked By - Senaida (WPSolving Volunteer)