亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

Go Resiliency庫中timeout實(shí)現(xiàn)原理及源碼解析

 更新時間:2023年05月11日 08:43:27   作者:soft2967  
Go-Resiliency庫中的timeout是一種基于協(xié)程的超時機(jī)制,通過創(chuàng)建協(xié)程來執(zhí)行任務(wù)并設(shè)置超時時間,若任務(wù)執(zhí)行時間超時則中止協(xié)程并返回錯誤,需要詳細(xì)了解可以參考下文

1.go-resiliency簡介

? 今天看到項(xiàng)目里用到了go-resiliency這個庫,庫整體比較簡單,代碼量不大。主要實(shí)現(xiàn)go中幾種常見的模式:

后面分析下這幾種模式的實(shí)現(xiàn)

- circuit-breaker 熔斷器
- semaphore       信號量
- timeout         函數(shù)超時
- batching        批處理
- retriable       可重復(fù)

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)
  //執(zhí)行takesFiveSecond
  if err := dl.Run(takesFiveSecond); err != nil {
		t.Error(err)
	}
  //執(zhí)行takesTwentySecond
  if err := dl.Run(takesTwentySecond); err == ErrTimedOut {
		t.Error(err)
	}
}
  • 這里先dl := New(10 * time.Second)創(chuàng)建timeout對象Deadline,可以看到Deadline只有一個變量,就是超時時間。
  • 執(zhí)行函數(shù)調(diào)用dl.Run(takesFiveSecond),如果調(diào)用的函數(shù)執(zhí)行時間大于變量timeout,會返回失敗。

3.源碼實(shí)現(xiàn)如下

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

Deadline對象只有一個timeout成員變量

Run核心函數(shù):

//1. 可以看到Run函數(shù)有一個入?yún)⑹且粋€函數(shù),函數(shù)的原型為func (<-chan struct{}))error 也就是說我們傳入work變量就需要定義一個這個的簽名函數(shù)。
//2. Run函數(shù)返回error,這個返回實(shí)際是入?yún)ork函數(shù)返回的。
//3.為什么work函數(shù)變量,要有一個chan了? 這個主要為了能讓work函數(shù)里來控制,Run提前退出
func (d *Deadline) Run(work func(<-chan struct{}) error) error {
	result := make(chan error)
	stopper := make(chan struct{})
  //啟動一個協(xié)程
	go func() {
		value := work(stopper)
		select {
		case result <- value:
		case <-stopper:
		}
	}()
  //這里是判斷是否超時常用手法,通過select監(jiān)聽2個chan,一個讀取結(jié)果,一個為超時定時器。
  //如果在timeout時間內(nèi)未讀取到執(zhí)行結(jié)果,就觸發(fā)time.After返回超時
	select {
	case ret := <-result:
		return ret
	case <-time.After(d.timeout):
		close(stopper)
		return ErrTimedOut
	}
}

Run函數(shù)定義:Run(work func(<-chan struct{}) error) error :

  • 可以看到Run函數(shù)有一個入?yún)⑹且粋€函數(shù),函數(shù)的原型為func (<-chan struct{}))error 也就是說我們傳入work變量就需要定義一個這個的簽名函數(shù)。
  • Run函數(shù)返回error,這個返回實(shí)際是入?yún)ork函數(shù)返回的。

4.擴(kuò)展一下

go語言里超時控制還有其他常用方式嗎

對就是context.WithTimeout,讓我們使用context.WithTimeout來重新實(shí)現(xiàn)上面的對象,只需要修改一個地方

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
	}
}

到此這篇關(guān)于Go Resiliency庫中timeout實(shí)現(xiàn)原理及源碼解析的文章就介紹到這了,更多相關(guān)Go Resiliency庫中timeout內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Go打印結(jié)構(gòu)體提升代碼調(diào)試效率實(shí)例詳解

    Go打印結(jié)構(gòu)體提升代碼調(diào)試效率實(shí)例詳解

    這篇文章主要介紹了Go打印結(jié)構(gòu)體提升代碼調(diào)試效率實(shí)例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2024-02-02
  • 一文詳解Go語言fmt標(biāo)準(zhǔn)庫的常用占位符使用

    一文詳解Go語言fmt標(biāo)準(zhǔn)庫的常用占位符使用

    這篇文章主要為大家詳細(xì)介紹了Go語言中fmt標(biāo)準(zhǔn)庫的常用占位符及其簡單使用,文中的示例代碼講解詳細(xì),對我們學(xué)習(xí)Go語言有一定的幫助,需要的可以參考一下
    2022-12-12
  • golang?中?channel?的詳細(xì)使用、使用注意事項(xiàng)及死鎖問題解析

    golang?中?channel?的詳細(xì)使用、使用注意事項(xiàng)及死鎖問題解析

    這篇文章主要介紹了golang?中?channel?的詳細(xì)使用、使用注意事項(xiàng)及死鎖分析,本文給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2022-03-03
  • 基于Go語言構(gòu)建RESTful API服務(wù)

    基于Go語言構(gòu)建RESTful API服務(wù)

    在實(shí)際開發(fā)項(xiàng)目中,你編寫的服務(wù)可以被其他服務(wù)使用,這樣就組成了微服務(wù)的架構(gòu);也可以被前端調(diào)用,這樣就可以前后端分離。那么,本文主要介紹什么是 RESTful API,以及 Go 語言是如何玩轉(zhuǎn) RESTful API 的
    2021-07-07
  • go-micro微服務(wù)JWT跨域認(rèn)證問題

    go-micro微服務(wù)JWT跨域認(rèn)證問題

    JWT 以 JSON 對象的形式安全傳遞信息。因?yàn)榇嬖跀?shù)字簽名,因此所傳遞的信息是安全的,這篇文章主要介紹了go-micro微服務(wù)JWT跨域認(rèn)證,需要的朋友可以參考下
    2023-01-01
  • Go語言常見錯誤之濫用getters/setters誤區(qū)實(shí)例探究

    Go語言常見錯誤之濫用getters/setters誤區(qū)實(shí)例探究

    在Go語言編程中,恰如其分地使用getters和setters是至關(guān)重要的,過度和不適當(dāng)?shù)厥褂盟鼈兛赡軐?dǎo)致代碼冗余、可讀性差和封裝不當(dāng),在本文中,我們將深入探討如何識別濫用getter和setter的情況,以及如何采取最佳實(shí)踐來避免這些常見的Go錯誤
    2024-01-01
  • Gorm更新零值問題解決思路與過程

    Gorm更新零值問題解決思路與過程

    這篇文章主要介紹了Gorm更新零值問題解決思路與過程,總的來說這并不是一道難題,那為什么要拿出這道題介紹?拿出這道題真正想要傳達(dá)的是解題的思路,以及不斷優(yōu)化探尋最優(yōu)解的過程。希望通過這道題能給你帶來一種解題優(yōu)化的思路
    2023-01-01
  • 一文詳解Golang的中間件設(shè)計(jì)模式

    一文詳解Golang的中間件設(shè)計(jì)模式

    最近在看一些rpc框架的使用原理和源碼的時候,對中間件的實(shí)現(xiàn)非常感興趣,所以這篇文章就來和大家聊聊Golang的中間件設(shè)計(jì)模式,希望對大家有所幫助
    2023-03-03
  • Golang Gob編碼(gob包的使用詳解)

    Golang Gob編碼(gob包的使用詳解)

    這篇文章主要介紹了Golang Gob編碼(gob包的使用詳解),具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2021-05-05
  • go 代碼的調(diào)試---打印調(diào)用堆棧的實(shí)例

    go 代碼的調(diào)試---打印調(diào)用堆棧的實(shí)例

    下面小編就為大家?guī)硪黄猤o 代碼的調(diào)試---打印調(diào)用堆棧的實(shí)例。小編覺得挺不錯的,現(xiàn)在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2017-10-10

最新評論