From 9cbbd3957a729b68d7ebbeeb3cc6161c01591d39 Mon Sep 17 00:00:00 2001 From: Eduard Urbach Date: Thu, 28 Mar 2024 00:30:49 +0100 Subject: [PATCH] Improved performance --- Request.go | 7 ++++++- Server.go | 26 +++++++++++++------------- 2 files changed, 19 insertions(+), 14 deletions(-) diff --git a/Request.go b/Request.go index ed067b3..f820237 100644 --- a/Request.go +++ b/Request.go @@ -1,6 +1,10 @@ package web -import "git.akyoto.dev/go/router" +import ( + "bufio" + + "git.akyoto.dev/go/router" +) // Request is an interface for HTTP requests. type Request interface { @@ -14,6 +18,7 @@ type Request interface { // request represents the HTTP request used in the given context. type request struct { + reader *bufio.Reader scheme string host string method string diff --git a/Server.go b/Server.go index c30d991..e35449c 100644 --- a/Server.go +++ b/Server.go @@ -26,8 +26,8 @@ type Server interface { // server is an HTTP server. type server struct { - pool sync.Pool handlers []Handler + contextPool sync.Pool router *router.Router[Handler] errorHandler func(Context, error) } @@ -55,10 +55,7 @@ func NewServer() Server { }, } - s.pool.New = func() any { - return s.newContext() - } - + s.contextPool.New = func() any { return s.newContext() } return s } @@ -118,19 +115,21 @@ func (s *server) Use(handlers ...Handler) { // handleConnection handles an accepted connection. func (s *server) handleConnection(conn net.Conn) { - defer conn.Close() - reader := bufio.NewReader(conn) - var ( - ctx *context + ctx = s.contextPool.Get().(*context) method string url string ) + ctx.reader.Reset(conn) + + defer conn.Close() + defer s.contextPool.Put(ctx) + for { // Search for a line containing HTTP method and url for { - message, err := reader.ReadString('\n') + message, err := ctx.reader.ReadString('\n') if err != nil { return @@ -154,14 +153,13 @@ func (s *server) handleConnection(conn net.Conn) { lastSpace = len(message) } - ctx = s.pool.Get().(*context) url = message[space+1 : lastSpace] break } // Add headers until we meet an empty line for { - message, err := reader.ReadString('\n') + message, err := ctx.reader.ReadString('\n') if err != nil { return @@ -188,6 +186,8 @@ func (s *server) handleConnection(conn net.Conn) { // Handle the request s.handleRequest(ctx, method, url, conn) + + // Clean up the context ctx.request.headers = ctx.request.headers[:0] ctx.request.body = ctx.request.body[:0] ctx.response.headers = ctx.response.headers[:0] @@ -195,7 +195,6 @@ func (s *server) handleConnection(conn net.Conn) { ctx.params = ctx.params[:0] ctx.handlerCount = 0 ctx.status = 200 - s.pool.Put(ctx) } } @@ -218,6 +217,7 @@ func (s *server) newContext() *context { return &context{ server: s, request: request{ + reader: bufio.NewReader(nil), body: make([]byte, 0), headers: make([]header, 0, 8), params: make([]router.Parameter, 0, 8),