you are better than you think

sync.Pool使用场景–gin之context维护

· by thur · Read in about 1 min · (56 Words)
golang sync.Pool

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) {
    ...
}

Comments