go - 如何从长时间运行的 goroutine 发送更新?
问题描述
我有一个长期工作的 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的新手。经过大量的反复试验和谷歌搜索,我已经达到了上面的代码。它现在正在工作。当我看到它时,我仍然觉得它并不直观(这很可能是因为,我仍在尝试学习 Go 的做事方式)。所以我的问题是,我可以将其重构为更好的形状吗?是否有一些适用于这种场景的现有模式?或者,如果有一些完全不同的方法可以在作业运行时继续发送定期更新?
此外,任何改进我的 golang 并发性的建议也值得赞赏。:)
提前致谢!
解决方案
考虑使用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 进度更新的地方。
推荐阅读
- python - 关于密码python游戏的问题
- python - 为什么我的 json.loads() 调用不正确地格式化字符串?
- reactjs - 刷新令牌后通过调用相同的请求来处理刷新令牌
- css - 在 Xamarin.Forms 中围绕图像环绕文本
- javascript - 更改反应路由器链接的顺序
- ios - 可以在 SwiftUI 中实现“ScrollView”交互式键盘关闭吗?
- c++ - 使用插槽创建对话框
- asp.net - Windows 身份验证不适用于 Web 应用程序项目?
- bixby - 如何将收集的值传递给重新计划的操作?
- python - 编写一个 python 代码,仅使用一个循环从列表中找出最大和第二个最大数