Bug Report
在SSE等流式响应模式中(返回时间很长),需要获取Response
如下代码,会报错
response, err := gout.New().
WithContext(ctx).
SetTimeout(100 * time.Second).
SetMethod("POST").
SetURL(url).
SetJSON(request).
Response()
if err != nil {
panic(err.Error())
}
defer response.Body.Close()
// 读取Response.Body
for {
_, err := response.Body.Read(....)
}
当WithContext(ctx)在SetTimeout上面时,读取Response.Body(一段时间后)会出现context cancel的异常
产生BUG原因:
func (s *Setting) SetTimeout(d time.Duration) {
s.Index++
s.TimeoutIndex = s.Index
s.Timeout = d
}
// retry模块需要context.Context,所以这里也返回context.Context
func (r *Req) GetContext() context.Context {
if r.Timeout > 0 && r.TimeoutIndex > r.ctxIndex {
r.c, r.cancel = context.WithTimeout(context.Background(), r.Timeout) // 当`WithContext(ctx)`在`SetTimeout`上面时,会执行此行
}
return r.c
}
// Response 获取原始http.Response数据结构
func (r *Req) Response() (rsp *http.Response, err error) {
_, rsp, err = r.getReqAndRsp()
defer r.Reset() // 此处会调用r.cancel
return
}
因为r.cancel被调用,r.c会直接退出
解决办法
将setTimeout放在withContext上面
SetTimeout(100 * time.Second).
WithContext(ctx).
Bug Report
在SSE等流式响应模式中(返回时间很长),需要获取Response
如下代码,会报错
当
WithContext(ctx)在SetTimeout上面时,读取Response.Body(一段时间后)会出现context cancel的异常产生BUG原因:
因为r.cancel被调用,r.c会直接退出
解决办法
将setTimeout放在withContext上面