标准库实现(可测试)的gocron函数。

huangapple go评论85阅读模式
英文:

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")
}

huangapple
  • 本文由 发表于 2023年3月9日 00:25:35
  • 转载请务必保留本文链接:https://go.coder-hub.com/75675643.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定