sync.Pool使用场景–gin之context维护
gin是开源的优秀golang web框架之一,github repo:https://github.com/gin-gonic/gin
gin的pool是sync.Pool类型
Engine struct {
...
pool sync.Pool
...
}
gin的context通过pool来get和put,也就是使用了sync.Pool进行维护,见代码红色部分
// Conforms to the http.Handler interface.
func (engine *Engine) ServeHTTP(w http.ResponseWriter, req *http.Request) {
c := engine.pool.Get().(*Context)
c.writermem.reset(w)
c.Request = req
c.reset()
engine.handleHTTPRequest(c
)
engine.pool.Put(c
)
}
gin在使用context时候用到了sync.Pool,sync.Pool的简单总结见这篇文章, 临时是指对象池的没有引用的对象在每两分钟一次的GC中会被全部清理掉。
GC时正在使用的context是有引用的,因此不会被清理。当engine.handleHTTPRequest(c)
执行完的时候,这个请求已经被处理完成。put回pool的context此时是已经使用过的,并且里面的数据是上次使用的历史数据,因此被清理掉也没有关系。为了应对躲过GC的context,当从pool中get到一个context,除了request被赋值(为新请求的request)而其字段都要被reset(见代码中的粗体部分)。
engine.handleHTTPRequest(c)
这个函数是不是看起来是不是有点眼熟? 直觉上很类似一线处理函数http.HandlerFunc 。那看下定义,果然:
type HandlerFunc func(*Context)
func (engine *Engine) handleHTTPRequest(context *Context) {
...
}