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>
答案
行为上的差异源于 net/http 包中缓冲区的使用。根据响应的大小和配置,正文在读取之前可能会部分或完全缓冲。这意味着当使用 json.NewDecoder().Decode() 时,过期的上下文可能不会阻止缓冲数据被访问。
为了说明这一点,创建了一个测试服务器,故意延迟响应正文。它模拟了 net/http 包的部分缓冲行为。当使用此测试服务器执行 readDoesntFail() 时,确实触发了预期上下文截止时间超出错误。
结论
在用户代码中观察到的行为突出了潜在的可能性在上下文截止日期中使用 json.NewDecoder().Decode() 的注意事项。重要的是要注意,如果响应正文很大并且已完全缓冲,则上下文截止日期可能不会按预期执行。
以上是当响应主体被缓冲时, json.NewDecoder().Decode() 是否遵守上下文截止日期?的详细内容。更多信息请关注PHP中文网其他相关文章!