Go 如何轮询HTTP端点并更新数据源?
我正在尝试做一些需要更长时间的CRUD操作。我想出了一个方法来证明我的问题: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(
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()