概述
context
是Go中廣泛使用的程式包,由Google官方開發,在1.7版本引入。它用來簡化在多個go routine傳遞上下文資料、(手動/逾時)中止routine樹等操作,比如,官方http包使用context傳遞請求的上下文資料,gRpc使用context來終止某個請求産生的routine樹。每個Context應該視為隻讀的,通過WithCancel、WithDeadline、WithTimeout和WithValue函數可以基于現有的一個Context(稱為父Context)派生出一個新的Context(稱為子Context)。其中WithCancel、WithDeadline和WithTimeout函數除了傳回一個派生的Context以外,還會傳回一個與之關聯CancelFunc類型的函數,用于關閉Context。通過調用CancelFunc來關閉關聯的Context時,基于該Context所派生的Context也都會被關閉,并且會将自己從父Context中移除,停止和它相關的timer。
核心接口
1 2 3 4 5 6 | |
根據如上接口顯示對每個方法介紹
-
會傳回一個channel,當該context被取消的時候,該channel會被關閉,同時對應的使用該context的routine也應該結束并傳回。Done
-
中的方法是協程安全的,這也就代表了在父routine中建立的context,可以傳遞給任意數量的routine并讓他們同時通路。Context
-
會傳回一個逾時時間,routine獲得了逾時時間後,可以對某些io操作設定逾時時間。Deadline
-
可以讓routine共享一些資料,當然獲得資料是協程安全的。Value
在請求處理的過程中,會調用各層的函數,每層的函數會建立自己的routine,是一個routine樹。是以,context也應該反映并實作成一棵樹。
建立context
在建立context時會通過
context.Background
函數的傳回值是一個空的context,作為樹的根結點。并且提供4個常用函數去建立其子節點。
1 2 3 4 | |
需要注意的是每個函數都會傳回一個CancelFunc。調用CancelFunc對象将撤銷對應的Context對象,這樣父結點的所在的環境中,獲得了撤銷子節點context的權利,當觸發某些條件時,可以調用CancelFunc對象來終止子結點樹的所有routine。
我們在子集中可以通過
cxt.Done(
)是否為空來判斷。
1 2 3 4 | |
WithDeadline
和
WithTimeout
比
WithCancel
多了一個時間參數,它訓示context存活的最長時間。如果超過了過期時間,會自動撤銷它的子context。是以context的生命期是由父context的routine和
deadline
共同決定的。
WithValue
傳回parent的一個副本,該副本儲存了傳入的key/value,而調用Context接口的Value(key)方法就可以得到val。注意在同一個context中設定key/value,若key相同,值會被覆寫。
示例
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 | |