컨텍스트 기한 내에서 json.NewDecoder().Decode()의 예기치 않은 동작
컨텍스트 기한이 설정된 Go 프로그램에서는 응답이 ioutil.ReadAll()에서 읽은 본문은 오류(context.DeadlineExceeded)를 반환할 것으로 예상됩니다. 그러나 nil을 반환하는 json.NewDecoder(resp.Body).Decode()를 사용하여 응답 본문을 읽을 때는 이 동작이 관찰되지 않습니다.
문제를 더 자세히 살펴보겠습니다.
응답에 따라 net/http 패키지는 요청을 처리하기 위해 버퍼를 사용할 수 있습니다. 이는 수신 응답 본문을 수행하기 전에 부분적으로 또는 전체적으로 읽고 버퍼링될 수 있음을 의미합니다. 따라서 만료되는 컨텍스트로 인해 본문 읽기 완료가 방해되지 않을 수 있습니다.
이를 더 명확하게 설명하기 위해 의도적으로 응답을 부분적으로 지연시키는 테스트 HTTP 서버를 시작하도록 예제를 조정했습니다.
<code class="go">ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { s := []byte(`{"ip":"12.34.56.78"}`) w.Write(s[:10]) if f, ok := w.(http.Flusher); ok { f.Flush() } time.Sleep(time.Second * 6) w.Write(s[10:]) })) defer ts.Close() url = ts.URL readDoesntFail() readFails()</code>
이 테스트 서버는 ip.jsontest.com의 응답과 유사한 JSON 개체를 출력합니다. 이와 대조적으로 처음에는 본문 바이트 10개만 전달한 다음 플러시하고 나머지를 전송하기 전에 의도적으로 6초 동안 휴면 상태로 클라이언트에 만료 시간을 제공합니다.
이 서버에서 readDoesntFail()을 실행할 때 , 우리는 다음을 얻습니다:
before reading response body, context error is: context deadline exceeded panic: Get "http://127.0.0.1:38230": context deadline exceeded goroutine 1 [running]: main.readDoesntFail() /tmp/sandbox721114198/prog.go:46 +0x2b4 main.main() /tmp/sandbox721114198/prog.go:28 +0x93
이제 업데이트된 예제에서 json.Decoder.Decode()는 정보가 아직 버퍼링되지 않았기 때문에 연결에서 읽으려고 노력하며 컨텍스트 만료 시 메시지를 표시할 수 있습니다. 만료된 컨텍스트로 인해 오류가 발생했습니다.
위 내용은 Go에서 `ioutil.ReadAll()`이 컨텍스트 기한 내에 있을 때 `json.NewDecoder().Decode()`가 컨텍스트 기한 오류를 반환하지 않는 이유는 무엇입니까?의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!