为什么我要在处理程序中为goroutines制作上下文的副本



我最近开始在Go中重写我的一些Python服务,以加快它们的速度,并看到了gin文档的这一部分:https://github.com/gin-gonic/gin#goroutines-内部中间件

所以我理解说明书,但我想明白为什么?复制的意义是什么?如果我不为处理程序中的goroutines复制上下文,会带来什么问题?

Gin-gonic本身是异步的,这使它非常棒。如果您在处理程序中使用并发性,很可能会遇到Context(结构(进入时的情况

  • 过时了,因为它保存着来自每个请求的数据(参数、受互斥体保护的密钥(

  • 空,这将导致回退到默认上下文

以下是它的样子:

type Context struct {
writermem responseWriter
Request   *http.Request
Writer    ResponseWriter
Params   Params
handlers HandlersChain
index    int8
fullPath string
engine       *Engine
params       *Params
skippedNodes *[]skippedNode
// This mutex protects Keys map.
mu sync.RWMutex
// Keys is a key/value pair exclusively for the context of each request.
Keys map[string]any
// Errors is a list of errors attached to all the handlers/middlewares who used this context.
Errors errorMsgs
// Accepted defines a list of manually accepted formats for content negotiation.
Accepted []string
// queryCache caches the query result from c.Request.URL.Query().
queryCache url.Values
// formCache caches c.Request.PostForm, which contains the parsed form data from POST, PATCH,
// or PUT body parameters.
formCache url.Values
// SameSite allows a server to define a cookie attribute making it impossible for
// the browser to send this cookie along with cross-site requests.
sameSite http.SameSite

}

为了预见这样的问题和竞争条件,当处理程序使用go并发时,必须使用Copy

这是一个引用自杜松子酒gonic储存库:

// Copy returns a copy of the current context that can be safely used outside the request's scope.
// This has to be used when the context has to be passed to a goroutine.

最新更新