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

断路器设计模式 sleep vs time.AfterFunc

断路器设计模式 sleep vs time.AfterFunc

Go
杨魅力 2022-03-07 16:24:42
我正在尝试创建一个断路器模式,我想执行一个命令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.


查看完整回答
反对 回复 2022-03-07
  • 1 回答
  • 0 关注
  • 270 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
微信客服

购课补贴
联系客服咨询优惠详情

帮助反馈 APP下载

慕课网APP
您的移动学习伙伴

公众号

扫描二维码
关注慕课网微信公众号