Go json.NewDecoder().Decode() 上下文截止時間問題
在Go 程序中,上下文截止時間提供了一種設定超時的方法某些操作。但是,使用者在使用 json.NewDecoder().Decode() 時報告了意外行為。
用戶關注
用戶期望 json.NewDecoder()。 Decode() 以遵守程式設定的上下文截止日期。他們觀察到,正如預期的那樣,使用 ioutil.ReadAll() 讀取回應正文觸發了上下文截止日期超出錯誤。然而,當他們切換到 json.NewDecoder().Decode() 時,儘管經過的時間超過了截止日期,但沒有報告錯誤。
程式碼範例
ctx, _ := context.WithTimeout(context.Background(), time.Second*5)
req, err := http.NewRequestWithContext(ctx, http.MethodGet, url, nil)
...
time.Sleep(time.Second * 6)
fmt.Println("before reading response body, context error is:", ctx.Err())
err = json.NewDecoder(resp.Body).Decode(ipResponse)
if err != nil {
panic(err)
}
fmt.Println("Expected panic but there was none")
Answer
行為上的差異源於 net/http 包中緩衝區的使用。根據回應的大小和配置,正文在讀取之前可能會部分或完全緩衝。這表示當使用 json.NewDecoder().Decode() 時,過期的上下文可能不會阻止緩衝資料被存取。
為了說明這一點,創建了一個測試伺服器,故意延遲回應正文。它模擬了 net/http 套件的部分緩衝行為。當使用此測試伺服器執行 readDoesntFail() 時,確實觸發了預期的上下文截止日期超出錯誤。
結論
在用戶代碼中觀察到的行為突出了潛在的可能性在上下文截止日期中使用json.NewDecoder().Decode() 的注意事項。重要的是要注意,如果回應正文很大並且已完全緩衝,則上下文截止日期可能不會按預期執行。
免責聲明: 提供的所有資源部分來自互聯網,如果有侵犯您的版權或其他權益,請說明詳細緣由並提供版權或權益證明然後發到郵箱:[email protected] 我們會在第一時間內為您處理。
Copyright© 2022 湘ICP备2022001581号-3