gpt4 book ai didi

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

转载 作者:数据小太阳 更新时间:2023-10-29 03:26:45 25 4
gpt4 key购买 nike

我正在尝试创建一个 Circuit breaker pattern , 我想执行命令 exec.Command如果失败,在 X 定义的时间内重试,出于测试目的,我正在做这样的事情来测试 time.AfterFunc:

package main

import (
"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 适用于上面的代码,但不适用于下面的示例,我不得不将其替换为 sleep 以实现预期的结果:

package main

import (
"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/sh

sleep 3

为了测试,创建一个错误,我切换权限:

chmod -x sleep
chmod +x sleep

因此想知道使用 time.AfterFunctime.Sleep 之间有什么区别,什么是实现这种模式的最佳方式。

最佳答案

任何时候你点击 default case,选择都会立即结束。在上面的示例中,在您执行 AfterFunc 之后,for 循环会持续运行,直到 run 有项目(3 秒后)。繁忙的等待通常很糟糕。使用 sleep 解决方案,您永远不会有忙碌的等待,这很好。不过,我不确定我是否完全按照您在第二个示例中尝试使用嵌套选择完成的操作。

为什么你需要 channel 和异步?为什么不只是:

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.

关于design-patterns - 断路器设计模式 sleep vs time.AfterFunc,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39260658/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com