Go json.NewDecoder().Decode() 上下文截止時間問題
在Go 程式中,上下文截止時間提供了一種設定超時的方法某些操作。但是,使用者在使用 json.NewDecoder().Decode() 時報告了意外行為。
使用者問題
使用者期望 json.NewDecoder()。 Decode() 以遵守程式設定的上下文截止日期。他們觀察到,正如預期的那樣,使用 ioutil.ReadAll() 讀取回應正文會觸發上下文截止日期超出錯誤。然而,當他們切換到 json.NewDecoder().Decode() 時,儘管時間超過了截止日期,但沒有報告錯誤。
程式碼範例
<code class="go">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")</code>
答案
行為上的差異源自於緩衝區的使用。根據回應的大小和配置,正文在讀取之前可能會部分或完全緩衝。這表示當使用 json.NewDecoder().Decode() 時,過期的上下文可能不會阻止緩衝資料被存取。
為了說明這一點,創建了一個測試伺服器,故意延遲回應正文。它模擬了 net/http 套件的部分緩衝行為。當使用此測試伺服器執行 readDoesntFail() 時,確實觸發了預期上下文截止時間超出錯誤。
結論
在使用者程式碼中觀察到的行為突顯了潛在的可能性在上下文截止日期中使用json.NewDecoder().Decode() 的注意事項。重要的是要注意,如果回應正文很大並且已完全緩衝,則上下文截止日期可能不會按預期執行。
以上是當回應主體被緩衝時, json.NewDecoder().Decode() 是否遵守上下文截止日期?的詳細內容。更多資訊請關注PHP中文網其他相關文章!