golang Context應用舉例
視頻講解:

Context本質(zhì)
golang標準庫里Context實際上是一個接口(即一種編程規(guī)范、 一種約定)。
通過查看源碼里的注釋,我們得到如下約定:
Done()函數(shù)返回一個只讀管道,且管道里不存放任何元素(struct{}),所以用這個管道就是為了實現(xiàn)阻塞
Deadline()用來記錄到期時間,以及是否到期。
Err()用來記錄Done()管道關閉的原因,比如可能是因為超時,也可能是因為被強行Cancel了。
Value()用來返回key對應的value,你可以想像成Context內(nèi)部維護了一個map。
Context實現(xiàn)
go源碼里提供了Context接口的一個具體實現(xiàn),遺憾的是它只是一個空的Context,什么也沒做。
emptyCtx以小寫開頭,包外不可見,所以golang又提供了Background和TODO這2個函數(shù)讓我們能獲取到emptyCtx。
backgroud和todo明明是一模一樣的東西,就是emptyCtx,為什么要搞2個呢?真心求教,知道的同學請在評論區(qū)告訴我。
emptyCtx有什么用?創(chuàng)建Context時通常需要傳遞一個父Context,emptyCtx用來充當最初的那個Root Context。
With Value
當業(yè)務邏輯比較復雜,函數(shù)調(diào)用鏈很長時,參數(shù)傳遞會很復雜,如下圖:

f1產(chǎn)生的參數(shù)b要傳給f2,雖然f2并不需要參數(shù)b,但f3需要,所以b還是得往后傳。
如果把每一步產(chǎn)生的新變量都放到Context這個大容器里,函數(shù)之間只傳遞Context,需要什么變量時直接從Context里取,如下圖:

f2能從context里取到a和b,f4能從context里取到a、b、c、d。
Timeout
在上期視頻

里介紹了超時實現(xiàn)的核心原理,視頻中演示的done管道可以用Context的Done()來替代,Context的Done()管道什么時候會被關系呢?2種情況:
1. 通過context.WithCancel創(chuàng)建一個context,調(diào)用cancel()時會關閉context.Done()管道。
2.?通過context.WithTimeout創(chuàng)建一個context,當超過指定的時間或者調(diào)用cancel()時會關閉context.Done()管道。
Timeout的繼承問題
通過context.WithTimeout創(chuàng)建的Context,其壽命不會超過父Context的壽命。比如:
父Context設置了10號到期,5號誕生了子Context,子Context設置了100天后到期,則實際上10號的時候子Context也會到期。
父Context設置了10號到期,5號誕生了子Context,子Context設置了1天后到期,則實際上6號的時候子Context就會到期。
context超時在http請求中的實際應用
定心丸來了,最后說一遍:”context在實踐中真的很有用“
客戶端發(fā)起http請求時設置了一個2秒的超時時間:
服務端從Request里取提context,故意休息10秒鐘,同時監(jiān)聽context.Done()管道有沒有關閉。由于Request的context是2秒超時,所以服務端還沒休息夠context.Done()管道就關閉了。
萬水千山總是情,給個點贊行不行!