Improved performance

This commit is contained in:
Eduard Urbach 2024-03-28 00:30:49 +01:00
parent c3bb8336a3
commit 9cbbd3957a
Signed by: akyoto
GPG Key ID: C874F672B1AF20C0
2 changed files with 19 additions and 14 deletions

View File

@ -1,6 +1,10 @@
package web package web
import "git.akyoto.dev/go/router" import (
"bufio"
"git.akyoto.dev/go/router"
)
// Request is an interface for HTTP requests. // Request is an interface for HTTP requests.
type Request interface { type Request interface {
@ -14,6 +18,7 @@ type Request interface {
// request represents the HTTP request used in the given context. // request represents the HTTP request used in the given context.
type request struct { type request struct {
reader *bufio.Reader
scheme string scheme string
host string host string
method string method string

View File

@ -26,8 +26,8 @@ type Server interface {
// server is an HTTP server. // server is an HTTP server.
type server struct { type server struct {
pool sync.Pool
handlers []Handler handlers []Handler
contextPool sync.Pool
router *router.Router[Handler] router *router.Router[Handler]
errorHandler func(Context, error) errorHandler func(Context, error)
} }
@ -55,10 +55,7 @@ func NewServer() Server {
}, },
} }
s.pool.New = func() any { s.contextPool.New = func() any { return s.newContext() }
return s.newContext()
}
return s return s
} }
@ -118,19 +115,21 @@ func (s *server) Use(handlers ...Handler) {
// handleConnection handles an accepted connection. // handleConnection handles an accepted connection.
func (s *server) handleConnection(conn net.Conn) { func (s *server) handleConnection(conn net.Conn) {
defer conn.Close()
reader := bufio.NewReader(conn)
var ( var (
ctx *context ctx = s.contextPool.Get().(*context)
method string method string
url string url string
) )
ctx.reader.Reset(conn)
defer conn.Close()
defer s.contextPool.Put(ctx)
for { for {
// Search for a line containing HTTP method and url // Search for a line containing HTTP method and url
for { for {
message, err := reader.ReadString('\n') message, err := ctx.reader.ReadString('\n')
if err != nil { if err != nil {
return return
@ -154,14 +153,13 @@ func (s *server) handleConnection(conn net.Conn) {
lastSpace = len(message) lastSpace = len(message)
} }
ctx = s.pool.Get().(*context)
url = message[space+1 : lastSpace] url = message[space+1 : lastSpace]
break break
} }
// Add headers until we meet an empty line // Add headers until we meet an empty line
for { for {
message, err := reader.ReadString('\n') message, err := ctx.reader.ReadString('\n')
if err != nil { if err != nil {
return return
@ -188,6 +186,8 @@ func (s *server) handleConnection(conn net.Conn) {
// Handle the request // Handle the request
s.handleRequest(ctx, method, url, conn) s.handleRequest(ctx, method, url, conn)
// Clean up the context
ctx.request.headers = ctx.request.headers[:0] ctx.request.headers = ctx.request.headers[:0]
ctx.request.body = ctx.request.body[:0] ctx.request.body = ctx.request.body[:0]
ctx.response.headers = ctx.response.headers[: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.params = ctx.params[:0]
ctx.handlerCount = 0 ctx.handlerCount = 0
ctx.status = 200 ctx.status = 200
s.pool.Put(ctx)
} }
} }
@ -218,6 +217,7 @@ func (s *server) newContext() *context {
return &context{ return &context{
server: s, server: s,
request: request{ request: request{
reader: bufio.NewReader(nil),
body: make([]byte, 0), body: make([]byte, 0),
headers: make([]header, 0, 8), headers: make([]header, 0, 8),
params: make([]router.Parameter, 0, 8), params: make([]router.Parameter, 0, 8),