为了账号安全,请及时绑定邮箱和手机立即绑定

如何从长时间运行的 goroutine 发送更新?

如何从长时间运行的 goroutine 发送更新?

Go
冉冉说 2023-06-05 16:59:55
我有一个 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 errorprogressLoop:    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}我是戈朗的新手。经过大量的反复试验和谷歌搜索,我已经达到了上面的代码。它现在正在工作。当我看到它时,我仍然觉得它不直观(这很可能是因为,我仍在努力学习 Go 的做事方式)。所以我的问题是,我可以将其重构为更好的形状吗?是否有一些适用于这种情况的现有模式?或者是否有一些完全不同的方法可以在作业运行时持续发送定期更新?此外,也感谢任何改进我的 golang 并发性的建议。:)
查看完整描述

1 回答

?
海绵宝宝撒

TA贡献1809条经验 获得超8个赞

考虑使用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 进度更新的地方。


查看完整回答
反对 回复 2023-06-05
  • 1 回答
  • 0 关注
  • 66 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信