我的编程空间,编程开发者的网络收藏夹
学习永远不晚

GoResiliency库中timeout实现原理及源码解析

短信预约 -IT技能 免费直播动态提醒
省份

北京

  • 北京
  • 上海
  • 天津
  • 重庆
  • 河北
  • 山东
  • 辽宁
  • 黑龙江
  • 吉林
  • 甘肃
  • 青海
  • 河南
  • 江苏
  • 湖北
  • 湖南
  • 江西
  • 浙江
  • 广东
  • 云南
  • 福建
  • 海南
  • 山西
  • 四川
  • 陕西
  • 贵州
  • 安徽
  • 广西
  • 内蒙
  • 西藏
  • 新疆
  • 宁夏
  • 兵团
手机号立即预约

请填写图片验证码后获取短信验证码

看不清楚,换张图片

免费获取短信验证码

GoResiliency库中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)
  //执行takesFiveSecond
  if err := dl.Run(takesFiveSecond); err != nil {
		t.Error(err)
	}
  //执行takesTwentySecond
  if err := dl.Run(takesTwentySecond); err == ErrTimedOut {
		t.Error(err)
	}
}
  • 这里先dl := New(10 * time.Second)创建timeout对象Deadline,可以看到Deadline只有一个变量,就是超时时间。
  • 执行函数调用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 ret
	case <-time.After(d.timeout):
		close(stopper)
		return ErrTimedOut
	}
}

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

  • 可以看到Run函数有一个入参是一个函数,函数的原型为func (<-chan struct{}))error 也就是说我们传入work变量就需要定义一个这个的签名函数。
  • 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 ret
	case <-ctx.Done():
		close(stopper)
		return ErrTimedOut
	}
}

到此这篇关于Go Resiliency库中timeout实现原理及源码解析的文章就介绍到这了,更多相关Go Resiliency库中timeout内容请搜索编程网以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程网!

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

GoResiliency库中timeout实现原理及源码解析

下载Word文档到电脑,方便收藏和打印~

下载Word文档

猜你喜欢

GoResiliency库中timeout实现原理及源码解析

Go-Resiliency库中的timeout是一种基于协程的超时机制,通过创建协程来执行任务并设置超时时间,若任务执行时间超时则中止协程并返回错误,需要详细了解可以参考下文
2023-05-19

OpenMPtaskconstruct实现原理及源码示例解析

这篇文章主要为大家介绍了OpenMPtaskconstruct实现原理及源码示例解析,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
2023-03-06

async-validator实现原理源码解析

这篇文章主要为大家介绍了async-validator实现原理源码解析,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
2023-01-11

goslice扩容实现原理源码解析

这篇文章主要为大家介绍了goslice扩容实现原理源码解析,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
2023-01-03

Python 虚拟机集合set实现原理及源码解析

这篇文章主要为大家介绍了Python 虚拟机集合set实现原理及源码解析,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
2023-03-21

简易vuex4核心原理及实现源码分析

这篇文章主要为大家介绍了简易vuex4核心原理及实现源码分析,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
2023-01-12

Golang WaitGroup 底层原理及源码解析

WaitGroup 是 Golang 中最常见的并发控制技术之一,它的作用我们可以简单类比为其他语言中多线程并发控制中的 join(),这篇文章主要介绍了Golang WaitGroup 底层原理及源码详解,需要的朋友可以参考下
2023-05-18

vue3源码分析reactivity实现原理

这篇文章主要为大家介绍了vue3源码分析reactivity实现原理详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
2023-01-28

深入理解Python虚拟机中列表(list)的实现原理及源码剖析

在本篇文章当中主要给大家介绍 cpython 虚拟机当中针对列表的实现,在 Python 中,List 是一种非常常用的数据类型,可以存储任何类型的数据,并且支持各种操作,如添加、删除、查找、切片等,在本篇文章当中将深入去分析这一点是如何实现的
2023-03-08

不容错过的HashMap实现原理及源码分析

哈希表(hash table)也叫散列表,是一种非常重要的数据结构,应用场景及其丰富,许多缓存技术(比如memcached)的核心其实就是在内存中维护一张大的哈希表,而HashMap的实现原理也常常出现在各类的面试题中,重要性可见一斑。本文
2023-06-02

深入理解Python虚拟机中整型(int)的实现原理及源码剖析

在本篇文章当中主要给大家介绍在cpython内部是如何实现整型数据int的,主要是分析int类型的表示方式,分析int类型的巧妙设计
2023-03-13

深入理解Python虚拟机中字节(bytes)的实现原理及源码剖析

在本篇文章当中主要给大家介绍在 cpython 内部,bytes 的实现原理、内存布局以及与 bytes 相关的一个比较重要的优化点—— bytes 的拼接,需要的可以参考一下
2023-03-24

深入理解Python虚拟机中复数(complex)的实现原理及源码剖析

在本篇文章当中主要给大家介绍在cpython虚拟机当中是如何实现复数complex这个数据类型的,这个数据类型在cpython当中一应该是一个算比较简单的数据类型了,非常容易理解
2023-03-14

深入理解Python虚拟机中字典(dict)的实现原理及源码剖析

这篇文章主要介绍了在 cpython 当中字典的实现原理,在本篇文章当中主要介绍在早期 python3 当中的版本字典的实现,现在的字典做了部分优化,希望对大家有所帮助
2023-03-23

OpenMP task construct实现原理源码分析

本篇内容主要讲解“OpenMP task construct实现原理源码分析”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“OpenMP task construct实现原理源码分析”吧!从编译器
2023-07-05

编程热搜

  • Python 学习之路 - Python
    一、安装Python34Windows在Python官网(https://www.python.org/downloads/)下载安装包并安装。Python的默认安装路径是:C:\Python34配置环境变量:【右键计算机】--》【属性】-
    Python 学习之路 - Python
  • chatgpt的中文全称是什么
    chatgpt的中文全称是生成型预训练变换模型。ChatGPT是什么ChatGPT是美国人工智能研究实验室OpenAI开发的一种全新聊天机器人模型,它能够通过学习和理解人类的语言来进行对话,还能根据聊天的上下文进行互动,并协助人类完成一系列
    chatgpt的中文全称是什么
  • C/C++中extern函数使用详解
  • C/C++可变参数的使用
    可变参数的使用方法远远不止以下几种,不过在C,C++中使用可变参数时要小心,在使用printf()等函数时传入的参数个数一定不能比前面的格式化字符串中的’%’符号个数少,否则会产生访问越界,运气不好的话还会导致程序崩溃
    C/C++可变参数的使用
  • css样式文件该放在哪里
  • php中数组下标必须是连续的吗
  • Python 3 教程
    Python 3 教程 Python 的 3.0 版本,常被称为 Python 3000,或简称 Py3k。相对于 Python 的早期版本,这是一个较大的升级。为了不带入过多的累赘,Python 3.0 在设计的时候没有考虑向下兼容。 Python
    Python 3 教程
  • Python pip包管理
    一、前言    在Python中, 安装第三方模块是通过 setuptools 这个工具完成的。 Python有两个封装了 setuptools的包管理工具: easy_install  和  pip , 目前官方推荐使用 pip。    
    Python pip包管理
  • ubuntu如何重新编译内核
  • 改善Java代码之慎用java动态编译

目录