翻譯自:Go Concurrency Patterns: Context
地址:https://blog.golang.org/context
簡介
在Go server端,每個請求都是通過新起goroutine來處理。請求處理程序通常會啓動其他goroutine來訪問後端,例如數據庫和RPC服務。處理該請求的goroutine集合通常需要訪問特定於請求的值,例如最終用戶的身份,授權令牌和請求的時限。當一個請求被取消或超時時,處理該請求的所有goroutine應該迅速退出,以便系統可以回收他們正在使用的資源。
在Google,我們開發了一個Context包,可以輕鬆地跨API邊界將請求範圍(request-scoped)的值,取消信號和截止日期(deadlines)傳遞給處理請求的所有goroutine。該軟件包可作爲Context公開使用。本文將介紹如何使用該package。
Context
Context包的核心是Context類型:
|
|
更詳細的介紹,參見godoc:https://golang.org/pkg/context/
Done方法返回一個channel,作爲代表Context運行的函數的取消信號:當channel關閉時,函數應該放棄它們的工作並返回。Err方法返回一個錯誤,指示Context被取消的原因。
因爲Done channel只用於接收的原因,Context沒有取消方法:接收取消信號的方法與發送信號方法往往不是同一個。特別是,當父操作(parent operation)爲子操作(sub-operations)啓動goroutines時,這些子操作應該不能取消父操作。相反,WithCancel函數(如下所述)提供了一種取消新的上下文值的方法。
Context是協程安全的。代碼中可以將單個Context傳遞給任意數量的goroutine,並在取消該Context時可以將信號傳遞給所有的goroutine。
最後期限(Deadline)方法允許函數決定他們是否應該開始工作;如果剩下的時間太少,可能就不值得了。代碼也可以使用期限(Deadline)來設置I/O操作的超時。
值(Value)允許Context攜帶請求範圍(request-scoped)的數據。該數據必須是協程安全的,以便多個goroutine可以同時使用。
Derived contexts
Context包提供了從現有Context值派生新Context值的函數。這些值形成一個樹:當一個Context被取消時,從它派生的所有Context也被取消。
Background是所有Context樹的根;它永遠不會被取消:
|
|
WithCancel和WithTimeout返回派生的Context值,該值可以比父Context早被取消。請求處理程序返回時,通常會取消與傳入請求關聯的Context。使用多個副本時,WithCancel對於取消冗餘請求也很有用。WithTimeout對於設置對後端服務器的請求的最後期限很有用:
|
|
WithValue提供了一種將請求範圍的值與Context關聯的方法:
|
|
< END >
喜歡就點個在看 or 轉發個朋友圈唄
衣舞晨風
推薦閱讀: