mirror of https://github.com/gin-gonic/gin.git
Merge branch 'sync_pool' into develop
Conflicts: logger.go
This commit is contained in:
commit
25e7330e65
66
gin.go
66
gin.go
|
@ -13,6 +13,7 @@ import (
|
||||||
"math"
|
"math"
|
||||||
"net/http"
|
"net/http"
|
||||||
"path"
|
"path"
|
||||||
|
"sync"
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
|
@ -44,11 +45,6 @@ type (
|
||||||
|
|
||||||
errorMsgs []errorMsg
|
errorMsgs []errorMsg
|
||||||
|
|
||||||
Config struct {
|
|
||||||
CacheSize int
|
|
||||||
Preallocated int
|
|
||||||
}
|
|
||||||
|
|
||||||
// Context is the most important part of gin. It allows us to pass variables between middleware,
|
// Context is the most important part of gin. It allows us to pass variables between middleware,
|
||||||
// manage the flow, validate the JSON of a request and render a JSON response for example.
|
// manage the flow, validate the JSON of a request and render a JSON response for example.
|
||||||
Context struct {
|
Context struct {
|
||||||
|
@ -75,19 +71,12 @@ type (
|
||||||
Engine struct {
|
Engine struct {
|
||||||
*RouterGroup
|
*RouterGroup
|
||||||
HTMLTemplates *template.Template
|
HTMLTemplates *template.Template
|
||||||
cache chan *Context
|
cache sync.Pool
|
||||||
handlers404 []HandlerFunc
|
handlers404 []HandlerFunc
|
||||||
router *httprouter.Router
|
router *httprouter.Router
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
|
||||||
DefaultConfig = Config{
|
|
||||||
CacheSize: 1024,
|
|
||||||
Preallocated: 512,
|
|
||||||
}
|
|
||||||
)
|
|
||||||
|
|
||||||
// Allows type H to be used with xml.Marshal
|
// Allows type H to be used with xml.Marshal
|
||||||
func (h H) MarshalXML(e *xml.Encoder, start xml.StartElement) error {
|
func (h H) MarshalXML(e *xml.Encoder, start xml.StartElement) error {
|
||||||
start.Name = xml.Name{"", "map"}
|
start.Name = xml.Name{"", "map"}
|
||||||
|
@ -131,32 +120,19 @@ func (a errorMsgs) String() string {
|
||||||
return buffer.String()
|
return buffer.String()
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewWithConfig(config Config) *Engine {
|
// Returns a new blank Engine instance without any middleware attached.
|
||||||
if config.CacheSize < 2 {
|
// The most basic configuration
|
||||||
panic("CacheSize must be at least 2")
|
func New() *Engine {
|
||||||
}
|
|
||||||
if config.Preallocated > config.CacheSize {
|
|
||||||
panic("Preallocated must be less or equal to CacheSize")
|
|
||||||
}
|
|
||||||
engine := &Engine{}
|
engine := &Engine{}
|
||||||
engine.RouterGroup = &RouterGroup{nil, "/", nil, engine}
|
engine.RouterGroup = &RouterGroup{nil, "/", nil, engine}
|
||||||
engine.router = httprouter.New()
|
engine.router = httprouter.New()
|
||||||
engine.router.NotFound = engine.handle404
|
engine.router.NotFound = engine.handle404
|
||||||
engine.cache = make(chan *Context, config.CacheSize)
|
engine.cache.New = func() interface{} {
|
||||||
|
return &Context{Engine: engine, Writer: &responseWriter{}}
|
||||||
// Fill it with empty contexts
|
|
||||||
for i := 0; i < config.Preallocated; i++ {
|
|
||||||
engine.cache <- &Context{Engine: engine, Writer: &responseWriter{}}
|
|
||||||
}
|
}
|
||||||
return engine
|
return engine
|
||||||
}
|
}
|
||||||
|
|
||||||
// Returns a new blank Engine instance without any middleware attached.
|
|
||||||
// The most basic configuration
|
|
||||||
func New() *Engine {
|
|
||||||
return NewWithConfig(DefaultConfig)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Returns a Engine instance with the Logger and Recovery already attached.
|
// Returns a Engine instance with the Logger and Recovery already attached.
|
||||||
func Default() *Engine {
|
func Default() *Engine {
|
||||||
engine := New()
|
engine := New()
|
||||||
|
@ -173,10 +149,6 @@ func (engine *Engine) NotFound404(handlers ...HandlerFunc) {
|
||||||
engine.handlers404 = handlers
|
engine.handlers404 = handlers
|
||||||
}
|
}
|
||||||
|
|
||||||
func (engine *Engine) CacheStress() float32 {
|
|
||||||
return 1.0 - float32(len(engine.cache))/float32(cap(engine.cache))
|
|
||||||
}
|
|
||||||
|
|
||||||
func (engine *Engine) handle404(w http.ResponseWriter, req *http.Request) {
|
func (engine *Engine) handle404(w http.ResponseWriter, req *http.Request) {
|
||||||
handlers := engine.combineHandlers(engine.handlers404)
|
handlers := engine.combineHandlers(engine.handlers404)
|
||||||
c := engine.createContext(w, req, nil, handlers)
|
c := engine.createContext(w, req, nil, handlers)
|
||||||
|
@ -185,7 +157,7 @@ func (engine *Engine) handle404(w http.ResponseWriter, req *http.Request) {
|
||||||
if !c.Writer.Written() {
|
if !c.Writer.Written() {
|
||||||
c.Data(404, MIMEPlain, []byte("404 page not found"))
|
c.Data(404, MIMEPlain, []byte("404 page not found"))
|
||||||
}
|
}
|
||||||
engine.reuseContext(c)
|
engine.cache.Put(c)
|
||||||
}
|
}
|
||||||
|
|
||||||
// ServeHTTP makes the router implement the http.Handler interface.
|
// ServeHTTP makes the router implement the http.Handler interface.
|
||||||
|
@ -204,8 +176,7 @@ func (engine *Engine) Run(addr string) {
|
||||||
/************************************/
|
/************************************/
|
||||||
|
|
||||||
func (engine *Engine) createContext(w http.ResponseWriter, req *http.Request, params httprouter.Params, handlers []HandlerFunc) *Context {
|
func (engine *Engine) createContext(w http.ResponseWriter, req *http.Request, params httprouter.Params, handlers []HandlerFunc) *Context {
|
||||||
select {
|
c := engine.cache.Get().(*Context)
|
||||||
case c := <-engine.cache:
|
|
||||||
c.Writer.reset(w)
|
c.Writer.reset(w)
|
||||||
c.Req = req
|
c.Req = req
|
||||||
c.Params = params
|
c.Params = params
|
||||||
|
@ -213,23 +184,6 @@ func (engine *Engine) createContext(w http.ResponseWriter, req *http.Request, pa
|
||||||
c.Keys = nil
|
c.Keys = nil
|
||||||
c.index = -1
|
c.index = -1
|
||||||
return c
|
return c
|
||||||
default:
|
|
||||||
return &Context{
|
|
||||||
Writer: &responseWriter{w, -1, false},
|
|
||||||
Req: req,
|
|
||||||
Params: params,
|
|
||||||
handlers: handlers,
|
|
||||||
index: -1,
|
|
||||||
Engine: engine,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (engine *Engine) reuseContext(c *Context) {
|
|
||||||
select {
|
|
||||||
case engine.cache <- c:
|
|
||||||
default:
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Adds middlewares to the group, see example code in github.
|
// Adds middlewares to the group, see example code in github.
|
||||||
|
@ -265,7 +219,7 @@ func (group *RouterGroup) Handle(method, p string, handlers []HandlerFunc) {
|
||||||
group.engine.router.Handle(method, p, func(w http.ResponseWriter, req *http.Request, params httprouter.Params) {
|
group.engine.router.Handle(method, p, func(w http.ResponseWriter, req *http.Request, params httprouter.Params) {
|
||||||
c := group.engine.createContext(w, req, params, handlers)
|
c := group.engine.createContext(w, req, params, handlers)
|
||||||
c.Next()
|
c.Next()
|
||||||
group.engine.reuseContext(c)
|
group.engine.cache.Put(c)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -67,11 +67,10 @@ func Logger() HandlerFunc {
|
||||||
}
|
}
|
||||||
end := time.Now()
|
end := time.Now()
|
||||||
latency := end.Sub(start)
|
latency := end.Sub(start)
|
||||||
stdlogger.Printf("[GIN] %v |%s %3d %s| %12v | %3.1f%% | %s %4s %s\n",
|
stdlogger.Printf("[GIN] %v |%s %3d %s| %12v | %s %4s %s\n",
|
||||||
end.Format("2006/01/02 - 15:04:05"),
|
end.Format("2006/01/02 - 15:04:05"),
|
||||||
color, c.Writer.Status(), reset,
|
color, c.Writer.Status(), reset,
|
||||||
latency,
|
latency,
|
||||||
c.Engine.CacheStress()*100,
|
|
||||||
requester,
|
requester,
|
||||||
c.Req.Method, c.Req.URL.Path,
|
c.Req.Method, c.Req.URL.Path,
|
||||||
)
|
)
|
||||||
|
|
Loading…
Reference in New Issue