Go語言中的上下文取消操作詳解

2022-09-24 18:21:09 字數 1560 閱讀 7056

前言

許多使用go的人,都會用到它的上下文庫。大多數使用 context 進行下游操作,比如發出http呼叫,或者從資料庫獲取資料,或者在協程中執行非同步操作。最常見的用法是傳遞可由所有下游操作使用的公共資料。然而,乙個不太為人所知,但非常有用的上下文特性是,它能夠在中途取消或停止乙個操作。

本篇文章將解釋我們如何利用上下文庫的取消特性,並通過一些模式和最佳實踐來使用取消,使你的程式更快、更健壯。

為什麼需要取消?

簡而言之,我們需要取消,以防止我們的系統做不不需要的工作。

考慮http伺服器對資料庫的呼叫的常見情況,並將查詢的資料返回給客戶端:

時間圖,如果一切都很完美,就會是這樣的:

但是,如果客戶端取消了中間的請求,會發生什麼呢?例如,如果客戶端關閉了他們的瀏覽器,這可能會發生。如果沒有取消,應用伺服器和資料庫將繼續執行它們的工作,即使工作的結果將被浪費:

理想情況下,如果我們知道程序(在本例中是http請求)停止了,我們希望流程的所有下游元件停止工作:

1、上下文取消

現在我們知道了為什麼需要取消,讓我們來看看如何實現它。因為「取消」的事件與交易或正在執行的操作高度相關,所以它與上下文**在一起是很自然的。

取消的有兩個方面,你可能想要實現:

2、監聽取消事件

上下文型別提供了 done() 方法,每當上下文收到取消事件時,它都會返回接收空 struct{} 型別的通道。監聽取消事件就像等待

例如,讓我們考慮乙個http伺服器,它需要兩秒鐘來處理乙個事件。如果在此之前請求被取消,我們程式設計客棧希望立即返回:

func main()

func operation2(ctx context.context)

res, err := client.do(req)

// if the request failed, log to stdout

if err != nil

// print the statuscode if the request succeeds

fmt.println("response received, status code:", res.statuscode)

}根據谷歌主頁對你的請求的響應速度,你將收到:

response received, status code: 200

或者request failed: get context deadline exceeded

你可以使用超時來實現上述兩個結果。

陷阱和警告

儘管go的上下文取消是乙個通用的工具,但是在繼續之前,有一些事情是你應該記住的。其中最重要的一點是, 上下文只能被取消一次 。

如果你想在同乙個操作中提出多個錯誤,那麼使用上下文取消可能不是最好的選擇。使用取消的最慣用的方法是,當你真正想要取消某些東西時,而不僅僅是通知下游程序,錯誤已經發生了。

你需要記住的另一件事是,相同的上下文例項應該傳遞給所有你可能想要取消的功能和例程。用 withtimeout 或 withcancel 來包裝已經可取消的上下文將會導致多種可能性,你的上下文可以被取消,並且應該避免。

總結本文標題: go語言中的上下文取消操作詳解

本文位址:

Go語言系列 十六 上下文context

在go http包的server中,每乙個請求在都有乙個對應的goroutine去處理。請求處理函式通常會啟動額外的goroutine用來訪問後端服務,比如資料庫和rpc服務。乙個上游服務通常需要訪問多個下游服務,比如終端使用者的身份認證資訊 驗證相關的token 請求的截止時間。當乙個請求被取消或...

jquery操作的上下文環境

jquery上下文環境是什麼東西?平常我們使用jquery的時候,好像沒怎麼關注過這個名詞,但是不管你關注與否,它確實是存在的,為什麼要說這個jquery的上下文環境呢?1.使用jquery上下文環境結合合適的jquery選擇器,能夠大大的提高選擇的效率 2.jquery的上下文環境在操作ifram...

python的with檔案操作與上下文

帶有 with 關鍵字的語句,它通常用在對於系統資源如檔案 資料庫連線 socket而言,應用程式開啟這些資源並執行完業務邏輯之後,必須做的一件事就是要關閉 斷開 該資源。比如 python 程式開啟乙個檔案,往檔案中寫內容,寫完之後,就要關閉該檔案,否則會出現什麼情況呢?極端情況下會出現 too ...