Go 如何轮询HTTP端点并更新数据源?

Go 如何轮询HTTP端点并更新数据源?,go,Go,我正在尝试做一些需要更长时间的CRUD操作。我想出了一个方法来证明我的问题: package main import ( "fmt" "math/rand" "time" ) func call(s int) { fmt.Println(s) } func get() int { num := rand.Intn(20-10) + 5 return num } func main(

我正在尝试做一些需要更长时间的CRUD操作。我想出了一个方法来证明我的问题:

package main

import (
    "fmt"
    "math/rand"
    "time"
)

func call(s int) {
    fmt.Println(s)
}

func get() int {
    num := rand.Intn(20-10) + 5
    return num
}

func main() {
    call(1)
    ticker := time.NewTicker(1000 * time.Millisecond)
    stop := make(chan bool, 1)
    check := make(chan string, 1)
    go func() {
        for {
            select {
            case <-stop:
                check <- "done" 
                    fmt.Println("stopped")
                return
            case <-ticker.C:
                randInt := get()
                if randInt == 11 {
                    call(randInt)
                    stop <- true
                } else {
                    call(randInt)
                }
            }
        }
    }()
    
    //fmt.Println(<-stop)
}
主程序包
进口(
“fmt”
“数学/兰德”
“时间”
)
func调用(s int){
fmt.Println(s)
}
func get()int{
数量:=rand.Intn(20-10)+5
返回数
}
func main(){
电话(1)
ticker:=time.NewTicker(1000*时间.毫秒)
停止:=制造(chan bool,1)
检查:=制造(chan字符串,1)
go func(){
为了{
挑选{

case为了限制尝试次数,我们只需要计算尝试次数,这对于现有的for循环来说是微不足道的

stop
频道中显示,您也打算将此设置为可取消,但此处的使用将无法按预期进行。为此,您可以使用
context.context
,稍后可以将其合并到接受上下文的其他调用中。否则,
sync.WaitGroup
是等待comp的预期方法莱顿

等待goroutine返回可以通过一个通道完成,但您不应该依赖于发送单个值。如示例所示,多个读取器(可能由于重构而在稍后添加)将导致另一方无法接收信号。如果您确实使用某个频道,则关闭该频道是广播信号的标准方式

利用这些信息,我们可以得出这个修改后的示例:

ctx,cancel:=context.WithCancel(context.Background())
推迟取消
最大尝试次数:=5
var wg sync.WaitGroup
工作组.添加(1)
go func(){
推迟工作组完成()
ticker:=time.NewTicker(1000*时间.毫秒)
电话(1)
对于i:=1;;i++{
如果i>=maxAttempts{
fmt.Println(“尝试次数过多”)
返回
}
挑选{

步骤2后的案例如何通知客户机?好问题,通过通知。通知将添加到数据库,从数据库通知将显示您有两件事情从
停止
,但只发送了一个值。除了明显的死锁可能性外,您是否试图使此可取消?
检查
似乎没有显示o任何东西,这也是什么目的?如果没有最后一次接收操作,程序不会等待goroutine完成。这就是您试图做的吗?是的@JimB,有什么方法可以实现这一点,而不是使用限制为5的
循环,或者这是正确的方法吗?我们不能只使用waitGroup以外的通道吗?抱歉对于太多的问题。谢谢@JimB,我会尝试一下,然后尽快回来。感谢您在
等待完成
频道
上的宝贵时间和想法。如果我不需要等待,但让例程完成工作,
是更好的方法。@Gibbs:您需要提供更多信息来回答这个问题。在您的示例中,您必须等待,其他人e程序只是存在,什么也不做。好吧,比方说。API返回202,然后启动一个go例程。go例程需要检查状态。状态检查请求可能失败/成功/需要更多时间。所提到的链接
启动另一个go例程
,在
通道
中设置一个值,几秒钟后最终关闭通道在这种情况下,我可以使用它吗?我的意思是,你觉得有什么问题吗?你可以根据自己的意愿构造异步任务,但如果没有你正在做的所有细节,我们无法告诉你如何进行。链接的示例只是另一种形式的等待goroutine完成,但使用通道来传达。如果你需要的话要在goroutine之间进行通信,那么是的,您可能需要使用一个通道。
ctx, cancel := context.WithCancel(context.Background())
defer cancel()

maxAttempts := 5

var wg sync.WaitGroup
wg.Add(1)
go func() {
    defer wg.Done()
    ticker := time.NewTicker(1000 * time.Millisecond)

    call(1)

    for i := 1; ; i++ {
        if i >= maxAttempts {
            fmt.Println("too many tries")
            return
        }

        select {
        case <-ctx.Done():
            fmt.Println("cancelled")
            return

        case <-ticker.C:
            randInt := get()
            call(randInt)
            if randInt == 11 {
                fmt.Println("OK")
                return
            }
        }
    }
}()

wg.Wait()