sync.Pool for rw
This commit is contained in:
parent
fd78380cb4
commit
787ead652d
58
ron.go
58
ron.go
@ -9,6 +9,7 @@ import (
|
|||||||
"net/http"
|
"net/http"
|
||||||
"os"
|
"os"
|
||||||
"strings"
|
"strings"
|
||||||
|
"sync"
|
||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -53,6 +54,12 @@ type (
|
|||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
var rwPool = sync.Pool{
|
||||||
|
New: func() any {
|
||||||
|
return &responseWriterWrapper{}
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
const (
|
const (
|
||||||
RequestID string = "request_id"
|
RequestID string = "request_id"
|
||||||
HeaderJSON string = "application/json"
|
HeaderJSON string = "application/json"
|
||||||
@ -78,7 +85,9 @@ func (w *responseWriterWrapper) Write(b []byte) (int, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (w *responseWriterWrapper) Flush() {
|
func (w *responseWriterWrapper) Flush() {
|
||||||
w.ResponseWriter.(http.Flusher).Flush()
|
if flusher, ok := w.ResponseWriter.(http.Flusher); ok {
|
||||||
|
flusher.Flush()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func defaultEngine() *Engine {
|
func defaultEngine() *Engine {
|
||||||
@ -117,8 +126,13 @@ func (e *Engine) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
handler = createStack(e.middleware...)(handler)
|
handler = createStack(e.middleware...)(handler)
|
||||||
rw := &responseWriterWrapper{ResponseWriter: w}
|
rw := rwPool.Get().(*responseWriterWrapper)
|
||||||
|
rw.ResponseWriter = w
|
||||||
|
rw.headerWritten = false
|
||||||
handler.ServeHTTP(rw, r)
|
handler.ServeHTTP(rw, r)
|
||||||
|
|
||||||
|
rw.Flush()
|
||||||
|
rwPool.Put(rw)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (e *Engine) Run(addr string) error {
|
func (e *Engine) Run(addr string) error {
|
||||||
@ -142,29 +156,41 @@ func (e *Engine) USE(middleware Middleware) {
|
|||||||
|
|
||||||
func (e *Engine) GET(path string, handler func(*CTX)) {
|
func (e *Engine) GET(path string, handler func(*CTX)) {
|
||||||
e.mux.HandleFunc(fmt.Sprintf("GET %s", path), func(w http.ResponseWriter, r *http.Request) {
|
e.mux.HandleFunc(fmt.Sprintf("GET %s", path), func(w http.ResponseWriter, r *http.Request) {
|
||||||
rw := &responseWriterWrapper{ResponseWriter: w}
|
rw := rwPool.Get().(*responseWriterWrapper)
|
||||||
|
rw.ResponseWriter = w
|
||||||
|
rw.headerWritten = false
|
||||||
handler(&CTX{W: rw, R: r, E: e, Ctx: r.Context()})
|
handler(&CTX{W: rw, R: r, E: e, Ctx: r.Context()})
|
||||||
|
rwPool.Put(rw)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
func (e *Engine) POST(path string, handler func(*CTX)) {
|
func (e *Engine) POST(path string, handler func(*CTX)) {
|
||||||
e.mux.HandleFunc(fmt.Sprintf("POST %s", path), func(w http.ResponseWriter, r *http.Request) {
|
e.mux.HandleFunc(fmt.Sprintf("POST %s", path), func(w http.ResponseWriter, r *http.Request) {
|
||||||
rw := &responseWriterWrapper{ResponseWriter: w}
|
rw := rwPool.Get().(*responseWriterWrapper)
|
||||||
|
rw.ResponseWriter = w
|
||||||
|
rw.headerWritten = false
|
||||||
handler(&CTX{W: rw, R: r, E: e, Ctx: r.Context()})
|
handler(&CTX{W: rw, R: r, E: e, Ctx: r.Context()})
|
||||||
|
rwPool.Put(rw)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
func (e *Engine) PUT(path string, handler func(*CTX)) {
|
func (e *Engine) PUT(path string, handler func(*CTX)) {
|
||||||
e.mux.HandleFunc(fmt.Sprintf("PUT %s", path), func(w http.ResponseWriter, r *http.Request) {
|
e.mux.HandleFunc(fmt.Sprintf("PUT %s", path), func(w http.ResponseWriter, r *http.Request) {
|
||||||
rw := &responseWriterWrapper{ResponseWriter: w}
|
rw := rwPool.Get().(*responseWriterWrapper)
|
||||||
|
rw.ResponseWriter = w
|
||||||
|
rw.headerWritten = false
|
||||||
handler(&CTX{W: rw, R: r, E: e, Ctx: r.Context()})
|
handler(&CTX{W: rw, R: r, E: e, Ctx: r.Context()})
|
||||||
|
rwPool.Put(rw)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
func (e *Engine) DELETE(path string, handler func(*CTX)) {
|
func (e *Engine) DELETE(path string, handler func(*CTX)) {
|
||||||
e.mux.HandleFunc(fmt.Sprintf("DELETE %s", path), func(w http.ResponseWriter, r *http.Request) {
|
e.mux.HandleFunc(fmt.Sprintf("DELETE %s", path), func(w http.ResponseWriter, r *http.Request) {
|
||||||
rw := &responseWriterWrapper{ResponseWriter: w}
|
rw := rwPool.Get().(*responseWriterWrapper)
|
||||||
|
rw.ResponseWriter = w
|
||||||
|
rw.headerWritten = false
|
||||||
handler(&CTX{W: rw, R: r, E: e, Ctx: r.Context()})
|
handler(&CTX{W: rw, R: r, E: e, Ctx: r.Context()})
|
||||||
|
rwPool.Put(rw)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -188,29 +214,41 @@ func (g *groupMux) USE(middleware Middleware) {
|
|||||||
|
|
||||||
func (g *groupMux) GET(path string, handler func(*CTX)) {
|
func (g *groupMux) GET(path string, handler func(*CTX)) {
|
||||||
g.mux.HandleFunc(fmt.Sprintf("GET %s", path), func(w http.ResponseWriter, r *http.Request) {
|
g.mux.HandleFunc(fmt.Sprintf("GET %s", path), func(w http.ResponseWriter, r *http.Request) {
|
||||||
rw := &responseWriterWrapper{ResponseWriter: w}
|
rw := rwPool.Get().(*responseWriterWrapper)
|
||||||
|
rw.ResponseWriter = w
|
||||||
|
rw.headerWritten = false
|
||||||
handler(&CTX{W: rw, R: r, E: g.engine, Ctx: r.Context()})
|
handler(&CTX{W: rw, R: r, E: g.engine, Ctx: r.Context()})
|
||||||
|
rwPool.Put(rw)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
func (g *groupMux) POST(path string, handler func(*CTX)) {
|
func (g *groupMux) POST(path string, handler func(*CTX)) {
|
||||||
g.mux.HandleFunc(fmt.Sprintf("POST %s", path), func(w http.ResponseWriter, r *http.Request) {
|
g.mux.HandleFunc(fmt.Sprintf("POST %s", path), func(w http.ResponseWriter, r *http.Request) {
|
||||||
rw := &responseWriterWrapper{ResponseWriter: w}
|
rw := rwPool.Get().(*responseWriterWrapper)
|
||||||
|
rw.ResponseWriter = w
|
||||||
|
rw.headerWritten = false
|
||||||
handler(&CTX{W: rw, R: r, E: g.engine, Ctx: r.Context()})
|
handler(&CTX{W: rw, R: r, E: g.engine, Ctx: r.Context()})
|
||||||
|
rwPool.Put(rw)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
func (g *groupMux) PUT(path string, handler func(*CTX)) {
|
func (g *groupMux) PUT(path string, handler func(*CTX)) {
|
||||||
g.mux.HandleFunc(fmt.Sprintf("PUT %s", path), func(w http.ResponseWriter, r *http.Request) {
|
g.mux.HandleFunc(fmt.Sprintf("PUT %s", path), func(w http.ResponseWriter, r *http.Request) {
|
||||||
rw := &responseWriterWrapper{ResponseWriter: w}
|
rw := rwPool.Get().(*responseWriterWrapper)
|
||||||
|
rw.ResponseWriter = w
|
||||||
|
rw.headerWritten = false
|
||||||
handler(&CTX{W: rw, R: r, E: g.engine, Ctx: r.Context()})
|
handler(&CTX{W: rw, R: r, E: g.engine, Ctx: r.Context()})
|
||||||
|
rwPool.Put(rw)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
func (g *groupMux) DELETE(path string, handler func(*CTX)) {
|
func (g *groupMux) DELETE(path string, handler func(*CTX)) {
|
||||||
g.mux.HandleFunc(fmt.Sprintf("DELETE %s", path), func(w http.ResponseWriter, r *http.Request) {
|
g.mux.HandleFunc(fmt.Sprintf("DELETE %s", path), func(w http.ResponseWriter, r *http.Request) {
|
||||||
rw := &responseWriterWrapper{ResponseWriter: w}
|
rw := rwPool.Get().(*responseWriterWrapper)
|
||||||
|
rw.ResponseWriter = w
|
||||||
|
rw.headerWritten = false
|
||||||
handler(&CTX{W: rw, R: r, E: g.engine, Ctx: r.Context()})
|
handler(&CTX{W: rw, R: r, E: g.engine, Ctx: r.Context()})
|
||||||
|
rwPool.Put(rw)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -568,11 +568,13 @@ func Test_newLogger(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var preallocatedHello = []byte("Hello")
|
||||||
|
|
||||||
func Benchmark_GET(b *testing.B) {
|
func Benchmark_GET(b *testing.B) {
|
||||||
engine := New()
|
engine := New()
|
||||||
|
|
||||||
engine.GET("/hello", func(c *CTX) {
|
engine.GET("/hello", func(c *CTX) {
|
||||||
c.W.Write([]byte("Hello"))
|
c.W.Write(preallocatedHello)
|
||||||
})
|
})
|
||||||
|
|
||||||
req := httptest.NewRequest(http.MethodGet, "/hello", nil)
|
req := httptest.NewRequest(http.MethodGet, "/hello", nil)
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user