我正在尝试创建一个断路器模式,我想执行一个命令exec.Command如果它失败,在 X 定义的时间内重试,为了测试目的,我正在做这样的事情来测试time.AfterFunc:package mainimport ( "fmt" "time")func myFunc() error { for i := 1; i < 10; i++ { fmt.Printf("i = %+v\n", i) if i%3 == 0 { return fmt.Errorf("error") } } return nil}func main() { run := make(chan struct{}, 1) run <- struct{}{} for { select { case <-run: err := myFunc() if err != nil { time.AfterFunc(3*time.Second, func() { run <- struct{}{} }) } default: } }}time.AfterFunc适用于上面的代码,但不适用于下面的示例,我必须用 a 替换它sleep才能达到预期的结果:package mainimport ( "fmt" "os/exec" "time")func Exec(done chan<- error) error { cmd := exec.Command("./start") if err := cmd.Start(); err != nil { return err } go func() { done <- cmd.Wait() }() return nil}func main() { var ( run = make(chan struct{}, 1) done = make(chan error, 1) ) Exec(done) for { select { case <-run: err := Exec(done) if err != nil { fmt.Println(err) // time.AfterFunc(3*time.Second, func() { time.Sleep(3 * time.Second) run <- struct{}{} } default: select { case err := <-done: fmt.Println(err) run <- struct{}{} } } }}的内容./sleep:#!/bin/shsleep 3为了测试,创建一个错误,我切换 perms:chmod -x sleepchmod +x sleeptime.AfterFunc因此想知道使用and之间有什么区别,time.Sleep以及什么是实现这种模式的最佳方式。
1 回答
MMMHUHU
TA贡献1834条经验 获得超8个赞
每当您遇到默认情况时,选择都会立即结束。在上面的示例中,在您执行AfterFuncfor 循环后,将持续运行直到run有项目(3 秒后)。忙碌的等待通常是不好的。使用该sleep解决方案,您永远不会有忙碌的等待,这很好。不过,我不确定我是否完全遵循您在第二个示例中使用嵌套选择来完成的工作。
为什么你需要通道和异步?为什么不只是:
retryCount := 0
for retryCount < 3 {
err := doSomethingScary()
if err == nil{
//success! return results!
} else{
//failure! wait and retry
time.Sleep(time.Second) //time.sleep is a good non-busy wait
}
}
// max tries exceeded. Return error.
- 1 回答
- 0 关注
- 270 浏览
添加回答
举报
0/150
提交
取消
