猿问

如何从长时间运行的 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

}

我是戈朗的新手。经过大量的反复试验和谷歌搜索,我已经达到了上面的代码。它现在正在工作。当我看到它时,我仍然觉得它不直观(这很可能是因为,我仍在努力学习 Go 的做事方式)。所以我的问题是,我可以将其重构为更好的形状吗?是否有一些适用于这种情况的现有模式?或者是否有一些完全不同的方法可以在作业运行时持续发送定期更新?


此外,也感谢任何改进我的 golang 并发性的建议。:)


冉冉说
浏览 95回答 1
1回答

海绵宝宝撒

考虑使用time.NewTicker,它向通道发送周期值。这是文档中的示例:package mainimport (    "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 进度更新的地方。
随时随地看视频慕课网APP

相关分类

Go
我要回答