为了账号安全,请及时绑定邮箱和手机立即绑定

在 Go 中,在 http 处理程序中使用带有 pgx 的上下文的正确方法是什么?

在 Go 中,在 http 处理程序中使用带有 pgx 的上下文的正确方法是什么?

Go
神不在的星期二 2022-12-19 19:57:40
更新 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或创建独立请求的其他一些脚本/实用程序来测试您的代码。我相信在那种情况下您不会看到取消。


查看完整回答
反对 回复 2022-12-19
  • 1 回答
  • 0 关注
  • 85 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信