golang中Context的使用場景總結

2021-10-12 12:01:26 字數 1361 閱讀 5790

場景一:rpc呼叫

在主goroutine上有4個rpc,rpc2/3/4是並行請求的,我們這裡希望在rpc2請求失敗之後,直接返回錯誤,並且讓rpc3/4停止繼續計算。這個時候,就使用的到context

場景二:pipeline

pipeline模式就是流水線模型,流水線上的幾個工人,有n個產品,乙個乙個產品進行組裝。其實pipeline模型的實現和context並無關係,沒有context我們也能用chan實現pipeline模型。但是對於整條流水線的控制,則是需要使用上context的。這篇文章pipeline patterns in go的例子是非常好的說明。這裡就大致對這個**進行下說明。

run******pipeline的流水線工人有三個,linelistsource負責將引數乙個個分割進行傳輸,lineparser負責將字串處理成int64,sink根據具體的值判斷這個資料是否可用。他們所有的返回值基本上都有兩個chan,乙個用於傳遞資料,乙個用於傳遞錯誤。(<-chan string, <-chan error)輸入基本上也都有兩個值,乙個是context,用於傳聲控制的,乙個是(in <-chan)輸入產品的。

我們可以看到,這三個工人的具體函式裡面,都使用switch處理了case <-ctx.done()。這個就是生產線上的命令控制。

場景三:超時請求

我們傳送rpc請求的時候,往往希望對這個請求進行乙個超時的限制。當乙個rpc請求超過10s的請求,自動斷開。當然我們使用cancelcontext,也能實現這個功能(開啟乙個新的goroutine,這個goroutine拿著cancel函式,當時間到了,就呼叫cancel函式)。

鑑於這個需求是非常常見的,context包也實現了這個需求:timerctx。具體例項化的方法是 withdeadline 和 withtimeout。

具體的timerctx裡面的邏輯也就是通過time.afterfunc來呼叫ctx.cancel的。

場景四:http伺服器的request互相傳遞資料

context還提供了valuectx的資料結構。

這個valuectx最經常使用的場景就是在乙個http伺服器中,在request中傳遞乙個特定值,比如有乙個中介軟體,做cookie驗證,然後把驗證後的使用者名稱存放在request中。

我們可以看到,官方的request裡面是包含了context的,並且提供了withcontext的方法進行context的替換。

在使用valuectx的時候需要注意一點,這裡的key不應該設定成為普通的string或者int型別,為了防止不同的中介軟體對這個key的覆蓋。最好的情況是每個中介軟體使用乙個自定義的key型別,比如這裡的fookey,而且獲取value的邏輯盡量也抽取出來作為乙個函式,放在這個middleware的同包中。這樣,就會有效避免不同包設定相同的key的衝突問題了。

golang中的標準庫context解讀

golang 中的建立乙個新的 goroutine 並不會返回像c語言類似的pid,所有我們不能從外部殺死某個goroutine,所有我就得讓它自己結束,之前我們用 channel select 的方式,來解決這個問題,但是有些場景實現起來比較麻煩,例如由乙個請求衍生出的各個 goroutine 之...

Golang併發控制 context的使用

我們已經知道waitgroup可以用於併發控制,但當遇到更複雜的場景時,例如主動取消goroutine或者使超時的goroutine自動退出等,waitgroup就無能為力。這個時候,就是context大有用武之地。包context定義了context型別,它跨api邊界和程序之間攜帶截止日期,取消...

深入Golang之context的用法詳解

context在golang的1.7版本之前,是在包golang.org x net context中的,但是後來發現其在很多地方都是需要用到的,所有在1.7開始被列入了golang的標準庫。context包專門用來簡化處理單個請求的多個goroutine之間與請求域的資料 取消訊號 截止時間等相關...