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")
Ответ
Расхождение в поведении связано с использованием буферов в пакете net/http. В зависимости от размера и конфигурации ответа тело ответа может быть частично или полностью буферизовано перед чтением. Это означает, что при использовании json.NewDecoder().Decode() истекший контекст может не препятствовать доступу к буферизованным данным.
Чтобы проиллюстрировать это, был создан тестовый сервер, который намеренно задерживал тело ответа. . Он имитировал поведение частичной буферизации пакета net/http. Когда readDoesntFail() был выполнен на этом тестовом сервере, действительно возникла ошибка превышения ожидаемого срока контекста.
Заключение
Поведение, наблюдаемое в пользовательском коде, подчеркивает потенциал предостережения относительно использования json.NewDecoder().Decode() с крайними сроками контекста. Важно помнить, что если тело ответа большое и полностью буферизовано, крайний срок контекста может не соблюдаться должным образом.
Отказ от ответственности: Все предоставленные ресурсы частично взяты из Интернета. В случае нарушения ваших авторских прав или других прав и интересов, пожалуйста, объясните подробные причины и предоставьте доказательства авторских прав или прав и интересов, а затем отправьте их по электронной почте: [email protected]. Мы сделаем это за вас как можно скорее.
Copyright© 2022 湘ICP备2022001581号-3