go-resiliency源码解析之-timeout

news/2025/2/13 21:52:02/

go-resiliency源码解析之-timeout

1.go-resiliency简介

​ 今天看到项目里用到了go-resiliency这个库,库整体比较简单,代码量不大。主要实现go中几种常见的模式:

后面分析下这几种模式的实现

- circuit-breaker 熔断器
- semaphore       信号量
- timeout         函数超时
- batching        批处理
- retriable       可重复

2.timeout模式

先看看模式的test用例

import ("errors""testing""time"
)func takesFiveSecond(stopper <-chan struct{}) error {time.Sleep(5 * time.Second)return nil
}func takesTwentySecond(stopper <-chan struct{}) error {time.Sleep(20 * time.Second)return nil
}func TestDeadline(t *testing.T) {dl := New(10 * time.Second)//执行takesFiveSecondif err := dl.Run(takesFiveSecond); err != nil {t.Error(err)}//执行takesTwentySecondif err := dl.Run(takesTwentySecond); err == ErrTimedOut {t.Error(err)}
}
  1. 这里先dl := New(10 * time.Second)创建timeout对象Deadline,可以看到Deadline只有一个变量,就是超时时间。

  2. 执行函数调用dl.Run(takesFiveSecond),如果调用的函数执行时间大于变量timeout,会返回失败。

3.源码实现如下

type Deadline struct {timeout time.Duration
}func New(timeout time.Duration) *Deadline {return &Deadline{timeout: timeout,}
}

Deadline对象只有一个timeout成员变量

Run核心函数:

//1. 可以看到Run函数有一个入参是一个函数,函数的原型为func (<-chan struct{}))error 也就是说我们传入work变量就需要定义一个这个的签名函数。
//2. Run函数返回error,这个返回实际是入参work函数返回的。
//3.为什么work函数变量,要有一个chan了? 这个主要为了能让work函数里来控制,Run提前退出
func (d *Deadline) Run(work func(<-chan struct{}) error) error {result := make(chan error)stopper := make(chan struct{})//启动一个协程go func() {value := work(stopper)select {case result <- value:case <-stopper:}}()//这里是判断是否超时常用手法,通过select监听2个chan,一个读取结果,一个为超时定时器。//如果在timeout时间内未读取到执行结果,就触发time.After返回超时select {case ret := <-result:return retcase <-time.After(d.timeout):close(stopper)return ErrTimedOut}
}

Run函数定义:Run(work func(<-chan struct{}) error) error :

  1. 可以看到Run函数有一个入参是一个函数,函数的原型为func (<-chan struct{}))error 也就是说我们传入work变量就需要定义一个这个的签名函数。
  2. Run函数返回error,这个返回实际是入参work函数返回的。

4.扩展一下,go语言里超时控制还有其他常用方式吗

对就是context.WithTimeout,让我们使用context.WithTimeout来重新实现上面的对象,只需要修改一个地方

import ("context""errors""time"
)var ErrTimedOut = errors.New("timed out waiting for function to finish")type ContextTimeOut struct {timeout time.Duration
}// New constructs a new Deadline with the given timeout.
func New(timeout time.Duration) *ContextTimeOut {return &ContextTimeOut{timeout: timeout,}
}func (d *ContextTimeOut) Run(work func(<-chan struct{}) error) error {result := make(chan error)stopper := make(chan struct{})go func() {value := work(stopper)select {case result <- value:case <-stopper:}}()ctx, _ := context.WithTimeout(context.Background(), d.timeout)select {case ret := <-result:return retcase <-ctx.Done():close(stopper)return ErrTimedOut}
}

http://www.ppmy.cn/news/62032.html

相关文章

Vue solt 插槽使用~

一、基本使用&#xff1a; 子组件&#xff1a; 在子组件中使用<slot></slot>给值留下位置&#xff0c; 可以得到父组件的值 <template> <div> <strong>ERROR:</strong> <slot></slot> </div> </template> …

Canal实战使用(集群部署)和原理解析

1.mysql数据同步工作原理 MySQL master将数据变更写入二进制日志(binary log&#xff0c;其中记录叫做二进制日志事件binary log events&#xff0c;可以通过 show binlog events 进行查看) MySQL slave将master的binary log events拷贝到它的中继日志(relay log) MySQL slav…

软考A计划-常用公式复习

点击跳转专栏>Unity3D特效百例点击跳转专栏>案例项目实战源码点击跳转专栏>游戏脚本-辅助自动化点击跳转专栏>Android控件全解手册点击跳转专栏>Scratch编程案例 &#x1f449;关于作者 专注于Android/Unity和各种游戏开发技巧&#xff0c;以及各种资源分享&am…

SQL知识汇总

什么时候用存储过程合适 当一个事务涉及到多个SQL语句时或者涉及到对多个表的操作时就要考虑用存储过程&#xff1b;当在一个事务的完成需要很复杂的商业逻辑时&#xff08;比如&#xff0c;对多个数据的操作&#xff0c;对多个状态的判断更改等&#xff09;要考虑&#xff1b…

Nmap安全工具使用手册

Nmap安全工具使用手册 什么是Nmap&#xff1f; Nmap(Network Mapper) 是一款自由、开源的网络探测和安全审核工具。它适用于Windows、Linux、UNIX等各种操作系统平台&#xff0c;可以帮助管理员或安全研究人员判断目标机器的状态和对应的服务程序&#xff0c;同时也能探查隐蔽…

【Linux网络】网络应用层的 http 和 https协议

文章目录 1、http协议1.1 认识URL1.2 http协议格式1.3 http的方法&#xff08;GET和POST&#xff09;1.4 状态码1.5 cookie1.6 短连接和长连接 2、https协议2.1 常见的加密方式2.2 探究https协议的加密2.3 CA证书 1、http协议 在之前学习序列化和反序列化的时候&#xff0c;认…

模糊PID模糊控制(清晰化方法梯形图实现)

模糊PID的模糊化请参看下面的博客文章: 博途PLC模糊PID三角隶属度函数指令(含Matlab仿真)_plc 模糊pid_RXXW_Dor的博客-CSDN博客三角隶属度函数FC,我们采用兼容C99标准的函数返回值写法,在FB里调用会更加直观,下面给大家具体讲解代码。常规写法的隶属度函数FC可以参看下…

人大金仓亮相国际金融展,打造“金融+产业+生态”创新模式

4月27日&#xff0c;以“荟萃金融科技成果&#xff0c;展现数字金融力量&#xff0c;谱写金融服务中国式现代化新篇章”为主题的2023中国国际金融展圆满落幕。作为已经举办30年的行业盛会&#xff0c;人大金仓再一次重磅亮相&#xff0c;全方位展示国产数据库前沿应用和创新服务…