英文:
Standard library implementation (testable) of gocron function
问题
我有一个要求,需要按照定时间隔运行一个作业(调用 REST 端点,然后将消息发送到队列)。目前我有这个函数,它使用了 gocron - https://github.com/go-co-op/gocron
然而,目前没有停止函数的机制,因此我无法进行清洁的测试。
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
}
它按照要求执行,并在所需的间隔内运行参数化函数,但我确信一定有一个更简洁的解决方案 - 可能是标准库提供的。
英文:
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 - 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.
答案1
得分: 1
你可以直接返回.Stop函数:
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
}
然后在你的测试中,你可以这样做:
called := 0
stop, err := RunSchedule("some-schedule", func() {
    called++
})
time.Sleep(time.Second * 1) // 根据需要进行操作
stop()
if called != 1 {
    t.Fail("called should be 1")
}
英文:
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")
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。


评论