前言
許多使用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 ...