我有一个长期工作的goroutine。当任务完成时,它推动的结果的通道。在此期间,作业运行的同时,我想保持状态为RUNNING更新的API。
到目前为止,我有以下代码:
func getProgressTimeout() <-chan time.Time {
return time.After(5 * time.Minute)
}
func runCommand(arg *Request) {
chanResult := make(chan Results)
go func(args *Request, c chan Results) {
resp, err := execCommand(args)
c <- Results{
resp: resp,
err: err,
}
}(arg, chanResult)
var err error
progressLoop:
for {
select {
case <-getProgressTimeout():
updateProgress() // this method will send status= RUNNING to a REST API
case out := <-chanResult:
err = jobCompleted(request, out)
break progressLoop
}
}
return err
}
我是golang的新手。经过大量的反复试验和谷歌搜索,我已经到达了上面的代码。现在正在工作。不过它不觉得直观的我,当我看着它(这很可能是因为,我仍然努力学习做事的方式去)。所以我的问题是,我可以将其重构为更好的形状吗?是否存在一些适用于这种情况的现有模式?或者,如果有一些完全不同的方法,以保持工作运行的同时发送定期更新?
此外,任何建议,以改善在我golang并发还赞赏。 :)
谢谢!
答案 0 :(得分:3)
请考虑使用time.NewTicker,它将周期值发送到通道。这是文档中的示例:
package main
import (
"fmt"
"time"
)
func main() {
ticker := time.NewTicker(time.Second)
defer ticker.Stop()
done := make(chan bool)
go func() {
time.Sleep(10 * time.Second)
done <- true
}()
for {
select {
case <-done:
fmt.Println("Done!")
return
case t := <-ticker.C:
fmt.Println("Current time: ", t)
}
}
}
请注意,嵌入式goroutine调用func
通过休眠10秒钟来模拟一个长任务,而调用方使用select
等待结果,同时还接收来自自动收报器的定期事件-这是您可以在其中进行API进度更新。