更新 1:似乎使用绑定到 HTTP 请求的上下文可能会导致“上下文取消”错误。但是,使用 context.Background() 作为父母似乎工作正常。 // This works, no 'context canceled' errors ctx, cancel := context.WithTimeout(context.Background(), 100*time.Second) // However, this creates 'context canceled' errors under mild load // ctx, cancel := context.WithTimeout(r.Context(), 100*time.Second) defer cancel() app.Insert(ctx, record)(更新了下面的代码示例以生成一个独立的重现示例)在 go 中,我有一个类似于以下代码的 http 处理程序。在对该端点的第一个 HTTP 请求中,我收到一个context cancelled错误。但是,数据实际上是插入到数据库中的。在对该端点的后续请求中,不会出现此类错误,并且数据也已成功插入数据库。问题:我context是否在 http 处理程序和pgx QueryRow 方法之间正确设置和传递?(如果没有,有更好的方法吗?)如果将此代码复制到 main.go 并运行go run main.go,转到localhost:4444/create并按住ctrl-R以产生轻微的负载,您应该会看到产生了一些上下文取消的错误。
1 回答
动漫人物
TA贡献1815条经验 获得超10个赞
TLDR:r.Context()
在生产中使用效果很好,使用浏览器进行测试是个问题。
一个 HTTP 请求获得它自己的上下文,当请求完成时该上下文被取消。这是一个特性,而不是一个错误。当请求被客户端中断或超时时,开发人员应该使用它并优雅地关闭执行。例如,取消的请求可能意味着客户端永远不会看到响应(交易结果),开发人员可以决定回滚该交易。
在生产中,对于正常设计/构建的 API,请求取消不会经常发生。通常,流程由服务器控制,服务器在取消请求之前返回结果。多个Client请求不会互相影响,因为他们得到独立的go-routine和context。同样,我们正在谈论正常设计/构建应用程序的快乐路径。您的示例应用程序看起来不错,应该可以正常工作。
问题是我们如何测试应用程序。我们使用浏览器并刷新单个浏览器会话,而不是创建多个独立的请求。我没有检查到底发生了什么,但假设浏览器终止了现有请求以便在您单击时运行新请求ctrl-R
。服务器看到该请求终止并将其作为上下文取消传达给您的代码。
尝试使用curl
或创建独立请求的其他一些脚本/实用程序来测试您的代码。我相信在那种情况下您不会看到取消。
- 1 回答
- 0 关注
- 85 浏览
添加回答
举报
0/150
提交
取消