我最近开始在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.