1 回答

TA贡献1804条经验 获得超2个赞
我刚刚对提供的解决方案进行了一些重构,现在它应该可以工作了。让我指导您完成相关更改。
函数doSomething_
func doSomething(ctx context.Context) error {
fmt.Printf("%v - doSomething: start\n", time.Now())
select {
case <-ctx.Done():
fmt.Printf("%v - doSomething: cancelled\n", time.Now())
return ctx.Err()
case <-time.After(3 * time.Second):
fmt.Printf("%v - doSomething: processed\n", time.Now())
return nil
}
}
它等待取消输入或在延迟几秒后3返回给调用者。它接受一个上下文来监听。
函数handleSomething_
func handleSomething(w http.ResponseWriter, r *http.Request) {
ctx := r.Context()
fmt.Printf("%v - handleRequestCtx: start\n", time.Now())
done := make(chan error)
go func() {
if err := doSomething(ctx); err != nil {
fmt.Printf("%v - handleRequestCtx: error %v\n", time.Now(), err)
done <- err
}
done <- nil
}()
select {
case <-ctx.Done():
fmt.Printf("%v - handleRequestCtx: cancelled\n", time.Now())
return
case err := <-done:
if err != nil {
fmt.Printf("%v - handleRequestCtx: error: %v\n", time.Now(), err)
w.WriteHeader(http.StatusInternalServerError)
return
}
fmt.Printf("%v - handleRequestCtx: processed\n", time.Now())
}
}
在这里,逻辑与您的逻辑非常相似。在 select 中,我们检查接收到的错误是否存在nil,并根据此返回正确的 HTTP 状态码给调用者。如果我们收到取消输入,我们将取消所有上下文链。
函数TestHandler_
func TestHandler(t *testing.T) {
r := mux.NewRouter()
r.HandleFunc("/demo", handleSomething)
srv := http.Server{
Addr: ":8000",
Handler: r,
}
var wg sync.WaitGroup
wg.Add(1)
go func() {
defer wg.Done()
if err := srv.ListenAndServe(); err != nil {
fmt.Println(err.Error())
}
}()
ctx := context.Background()
ctx, cancel := context.WithTimeout(ctx, 1*time.Second) // request canceled
// ctx, cancel := context.WithTimeout(ctx, 5*time.Second) // request processed
defer cancel()
req, _ := http.NewRequestWithContext(ctx, http.MethodGet, "http://localhost:8000/demo", nil)
client := http.Client{}
res, err := client.Do(req)
if err != nil {
fmt.Println(err.Error())
} else {
fmt.Printf("res status code: %d\n", res.StatusCode)
}
srv.Shutdown(ctx)
wg.Wait()
}
在这里,我们启动了一个 HTTP 服务器并通过http.Client. 可以看到有两条语句设置上下文超时。如果您使用带有评论的那个// request canceled,一切都将被取消,否则,如果您使用另一个,请求将被处理。
我希望这能澄清你的问题!
- 1 回答
- 0 关注
- 105 浏览
添加回答
举报