jjzjj

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

coder 2024-07-10 原文

我正在尝试创建一个 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/

有关design-patterns - 断路器设计模式 sleep vs time.AfterFunc的更多相关文章

  1. ruby-on-rails - Rails - 子类化模型的设计模式是什么? - 2

    我有一个模型:classItem项目有一个属性“商店”基于存储的值,我希望Item对象对特定方法具有不同的行为。Rails中是否有针对此的通用设计模式?如果方法中没有大的if-else语句,这是如何干净利落地完成的? 最佳答案 通常通过Single-TableInheritance. 关于ruby-on-rails-Rails-子类化模型的设计模式是什么?,我们在StackOverflow上找到一个类似的问题: https://stackoverflow.co

  2. ruby-on-rails - 使用 rails 4 设计而不更新用户 - 2

    我将应用程序升级到Rails4,一切正常。我可以登录并转到我的编辑页面。也更新了观点。使用标准View时,用户会更新。但是当我添加例如字段:name时,它​​不会在表单中更新。使用devise3.1.1和gem'protected_attributes'我需要在设备或数据库上运行某种更新命令吗?我也搜索过这个地方,找到了许多不同的解决方案,但没有一个会更新我的用户字段。我没有添加任何自定义字段。 最佳答案 如果您想允许额外的参数,您可以在ApplicationController中使用beforefilter,因为Rails4将参数

  3. Qt Designer的简单使用 - 2

    在前面两节的例子中,主界面窗口的尺寸和标签控件显示的矩形区域等,都是用C++代码编写的。窗口和控件的尺寸都是预估的,控件如果多起来,那就不好估计每个控件合适的位置和大小了。用C++代码编写图形界面的问题就是不直观,因此Qt项目开发了专门的可视化图形界面编辑器——QtDesigner(Qt设计师)。通过QtDesigner就可以很方便地创建图形界面文件*.ui,然后将ui文件应用到源代码里面,做到“所见即所得”,大大方便了图形界面的设计。本节就演示一下QtDesigner的简单使用,学习拖拽控件和设置控件属性,并将ui文件应用到Qt程序代码里。使用QtDesigner设计界面在开始菜单中找到「Q

  4. LC滤波器设计学习笔记(一)滤波电路入门 - 2

    目录前言滤波电路科普主要分类实际情况单位的概念常用评价参数函数型滤波器简单分析滤波电路构成低通滤波器RC低通滤波器RL低通滤波器高通滤波器RC高通滤波器RL高通滤波器部分摘自《LC滤波器设计与制作》,侵权删。前言最近需要学习放大电路和滤波电路,但是由于只在之前做音乐频谱分析仪的时候简单了解过一点点运放,所以也是相当从零开始学习了。滤波电路科普主要分类滤波器:主要是从不同频率的成分中提取出特定频率的信号。有源滤波器:由RC元件与运算放大器组成的滤波器。可滤除某一次或多次谐波,最普通易于采用的无源滤波器结构是将电感与电容串联,可对主要次谐波(3、5、7)构成低阻抗旁路。无源滤波器:无源滤波器,又称

  5. 计算机毕业设计ssm+vue基本微信小程序的小学生兴趣延时班预约小程序 - 2

    项目介绍随着我国经济迅速发展,人们对手机的需求越来越大,各种手机软件也都在被广泛应用,但是对于手机进行数据信息管理,对于手机的各种软件也是备受用户的喜爱小学生兴趣延时班预约小程序的设计与开发被用户普遍使用,为方便用户能够可以随时进行小学生兴趣延时班预约小程序的设计与开发的数据信息管理,特开发了小程序的设计与开发的管理系统。小学生兴趣延时班预约小程序的设计与开发的开发利用现有的成熟技术参考,以源代码为模板,分析功能调整与小学生兴趣延时班预约小程序的设计与开发的实际需求相结合,讨论了小学生兴趣延时班预约小程序的设计与开发的使用。开发环境开发说明:前端使用微信微信小程序开发工具:后端使用ssm:VU

  6. ruby-on-rails - 设计注册确认 - 2

    我在我的项目中有一个用户和一个管理员角色。我使用Devise创建了身份验证。在我的管理员角色中,我没有任何确认。在我的用户模型中,我有以下内容:devise:database_authenticatable,:confirmable,:recoverable,:rememberable,:trackable,:validatable,:timeoutable,:registerable#Setupaccessible(orprotected)attributesforyourmodelattr_accessible:email,:username,:prename,:surname,:

  7. ruby-on-rails - 设计通过 reset_password_token 获取用户 - 2

    我正在尝试创建密码规则来设计可恢复的密码更改。我通过passwords_controller.rb做了一个父类(superclass),但我需要在应用规则之前检查用户角色,但我所拥有的只是reset_password_token。 最佳答案 假设您的模型是用户:User.with_reset_password_token(your_token_here)Source 关于ruby-on-rails-设计通过reset_password_token获取用户,我们在StackOverflow

  8. ruby-on-rails - Rails 5,公寓和设计 : sign in with subdomains are not working - 2

    我已经使用Apartment设置了一个Rails5应用程序(1.2.0)和Devise(4.2.0)。由于某些DDNS问题,应用只能在app.myapp.com下访问(请注意子域app)。myapp.com重定向到app.myapp.com。我的用例是每个注册该应用的用户(租户)都应该通过他们的子域(例如tenant.myapp.com)访问他们的特定数据。用户不应限定在其子域内。基本上应该可以从任何子域登录。重定向到租户的正确子域由ApplicationController处理。根据Devise标准,登录页面位于app.myapp.com/users/sign_in。这就是问题开始的

  9. ruby-on-rails - 设计中的 ArgumentError::RegistrationsController#new 错误的参数数量(2 代表 0..1) - 2

    我在关注RyanbatesRailsCast的devise和omniauth(第235集-devise-and-omniauth-revised)。当我尝试使用Twitter登录时,标题中不断出现错误。defself.new_with_session(params,session)ifsession["devise.user_attributes"]new(session["devise.user_attributes"],without_protection:true)do|user|user.attributes=paramsuser.valid?end完整跟踪:C:/Ruby20

  10. ruby-on-rails - 使用用户或管理员模型和 Basecamp 样式子域设计登录 - 2

    我为Devise用户和管理员提供了不同的模型。我也在使用Basecamp风格的子域。除了我需要能够以用户或管理员身份进行身份验证的一些Controller和操作外,一切都运行良好。目前我有authenticate_user!在我的application_controller.rb中设置,对于那些只有管理员才能访问的Controller和操作,我使用skip_before_filter跳过它。不幸的是,我不能简单地指定每个Controller的身份验证要求,因为我仍然需要一些Controller和操作才能被用户或管理员访问。我尝试了一些方法都无济于事。看来,如果我移动authentica

随机推荐