Skip to content

Commit

Permalink
Optimize memory alignment by reordering fields
Browse files Browse the repository at this point in the history
  • Loading branch information
EwenQuim committed Dec 21, 2024
1 parent 0a1f2a2 commit a44aa13
Show file tree
Hide file tree
Showing 12 changed files with 64 additions and 53 deletions.
6 changes: 6 additions & 0 deletions .golangci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,12 @@ linters-settings:
locale: "US"
error: true

govet:
enable-all: true
disable:
- shadow


gofumpt:
extra-rules: true
staticcheck:
Expand Down
4 changes: 2 additions & 2 deletions ctx.go
Original file line number Diff line number Diff line change
Expand Up @@ -150,8 +150,8 @@ func (c netHttpContext[B]) SetStatus(code int) {

// readOptions are options for reading the request body.
type readOptions struct {
DisallowUnknownFields bool
MaxBodySize int64
DisallowUnknownFields bool
LogBody bool
}

Expand Down Expand Up @@ -295,7 +295,7 @@ func body[B any](c netHttpContext[B]) (B, error) {
body, err = readJSON[B](c.Req.Context(), c.Req.Body, c.readOptions)
}

c.Res.Header().Add("Server-Timing", Timing{"deserialize", time.Since(timeDeserialize), "controller > deserialize"}.String())
c.Res.Header().Add("Server-Timing", Timing{"deserialize", "controller > deserialize", time.Since(timeDeserialize)}.String())

return body, err
}
6 changes: 3 additions & 3 deletions errors.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,18 +29,18 @@ type HTTPError struct {
Type string `json:"type,omitempty" xml:"type,omitempty" description:"URL of the error type. Can be used to lookup the error in a documentation"`
// Short title of the error
Title string `json:"title,omitempty" xml:"title,omitempty" description:"Short title of the error"`
// HTTP status code. If using a different type than [HTTPError], for example [BadRequestError], this will be automatically overridden after Fuego error handling.
Status int `json:"status,omitempty" xml:"status,omitempty" description:"HTTP status code" example:"403"`
// Human readable error message
Detail string `json:"detail,omitempty" xml:"detail,omitempty" description:"Human readable error message"`
Instance string `json:"instance,omitempty" xml:"instance,omitempty"`
Errors []ErrorItem `json:"errors,omitempty" xml:"errors,omitempty"`
// HTTP status code. If using a different type than [HTTPError], for example [BadRequestError], this will be automatically overridden after Fuego error handling.
Status int `json:"status,omitempty" xml:"status,omitempty" description:"HTTP status code" example:"403"`
}

type ErrorItem struct {
More map[string]any `json:"more,omitempty" xml:"more,omitempty" description:"Additional information about the error"`
Name string `json:"name" xml:"name" description:"For example, name of the parameter that caused the error"`
Reason string `json:"reason" xml:"reason" description:"Human readable error message"`
More map[string]any `json:"more,omitempty" xml:"more,omitempty" description:"Additional information about the error"`
}

func (e HTTPError) Error() string {
Expand Down
6 changes: 3 additions & 3 deletions html.go
Original file line number Diff line number Diff line change
Expand Up @@ -57,11 +57,11 @@ type H map[string]any

// StdRenderer renders a template using the standard library templating engine.
type StdRenderer struct {
templateToExecute string
templates *template.Template
layoutsGlobs []string
fs fs.FS
data any
templates *template.Template
templateToExecute string
layoutsGlobs []string
}

var _ CtxRenderer = StdRenderer{}
Expand Down
2 changes: 1 addition & 1 deletion internal/common_context.go
Original file line number Diff line number Diff line change
Expand Up @@ -125,10 +125,10 @@ func (e QueryParamNotFoundError) Error() string {
}

type QueryParamInvalidTypeError struct {
Err error
ParamName string
ParamValue string
ExpectedType string
Err error
}

func (e QueryParamInvalidTypeError) Error() string {
Expand Down
4 changes: 2 additions & 2 deletions openapi_operations.go
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ func (o *OpenAPI) buildOpenapi3Response(description string, response Response) *

// openAPIResponse describes a response error in the OpenAPI spec.
type openAPIResponse struct {
Response
Code int
Description string
Response
Code int
}
4 changes: 2 additions & 2 deletions option.go
Original file line number Diff line number Diff line change
Expand Up @@ -332,10 +332,10 @@ func OptionAddError(code int, description string, errorType ...any) func(*BaseRo
// Response represents a fuego.Response that can be used
// when setting custom response types on routes
type Response struct {
// content-type of the response i.e application/json
ContentTypes []string
// user provided type
Type any
// content-type of the response i.e application/json
ContentTypes []string
}

// AddResponse adds a response to a route by status code
Expand Down
2 changes: 1 addition & 1 deletion perf.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,8 @@ import (
// Used in the Server-Timing header.
type Timing struct {
Name string
Dur time.Duration
Desc string
Dur time.Duration
}

// String returns a string representation of a Timing, as defined in https://www.w3.org/TR/server-timing/#the-server-timing-header-field
Expand Down
22 changes: 12 additions & 10 deletions route.go
Original file line number Diff line number Diff line change
Expand Up @@ -40,34 +40,36 @@ func NewBaseRoute(method, path string, handler any, openapi *OpenAPI, options ..
// BaseRoute is the base struct for all routes in Fuego.
// It contains the OpenAPI operation and other metadata.
type BaseRoute struct {
// handler executed for this route
Handler http.Handler

// OpenAPI operation
Operation *openapi3.Operation

// Ref to the whole OpenAPI spec. Be careful when changing directly its value directly.
OpenAPI *OpenAPI

Params map[string]OpenAPIParam

// HTTP method (GET, POST, PUT, PATCH, DELETE)
Method string

// URL path. Will be prefixed by the base path of the server and the group path if any
Path string

// handler executed for this route
Handler http.Handler

// namespace and name of the function to execute
FullName string
Params map[string]OpenAPIParam
Middlewares []func(http.Handler) http.Handler
FullName string

// Content types accepted for the request body. If nil, all content types (*/*) are accepted.
AcceptedContentTypes []string

// If true, the route will not be documented in the OpenAPI spec
Hidden bool
Middlewares []func(http.Handler) http.Handler

// Default status code for the response
DefaultStatusCode int

// Ref to the whole OpenAPI spec. Be careful when changing directly its value directly.
OpenAPI *OpenAPI
// If true, the route will not be documented in the OpenAPI spec
Hidden bool

// Override the default description
overrideDescription bool
Expand Down
2 changes: 1 addition & 1 deletion security.go
Original file line number Diff line number Diff line change
Expand Up @@ -100,8 +100,8 @@ func (security Security) ValidateToken(token string) (*jwt.Token, error) {
}

type AutoAuthConfig struct {
Enabled bool
VerifyUserInfo func(user, password string) (jwt.Claims, error) // Must check the username and password, and return the claims
Enabled bool
}

type contextKey string
Expand Down
8 changes: 4 additions & 4 deletions serve.go
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,7 @@ func HTTPHandler[ReturnType, Body any](s *Server, controller func(c ContextWithB
}

timeController := time.Now()
w.Header().Set("Server-Timing", Timing{"fuegoReqInit", timeController.Sub(timeCtxInit), ""}.String())
w.Header().Set("Server-Timing", Timing{"fuegoReqInit", "", timeController.Sub(timeCtxInit)}.String())

// CONTROLLER
ans, err := controller(ctx)
Expand All @@ -111,7 +111,7 @@ func HTTPHandler[ReturnType, Body any](s *Server, controller func(c ContextWithB
s.SerializeError(w, r, err)
return
}
w.Header().Add("Server-Timing", Timing{"controller", time.Since(timeController), ""}.String())
w.Header().Add("Server-Timing", Timing{"controller", "", time.Since(timeController)}.String())

if route.DefaultStatusCode != 0 {
w.WriteHeader(route.DefaultStatusCode)
Expand All @@ -130,14 +130,14 @@ func HTTPHandler[ReturnType, Body any](s *Server, controller func(c ContextWithB
return
}
timeAfterTransformOut := time.Now()
w.Header().Add("Server-Timing", Timing{"transformOut", timeAfterTransformOut.Sub(timeTransformOut), "transformOut"}.String())
w.Header().Add("Server-Timing", Timing{"transformOut", "transformOut", timeAfterTransformOut.Sub(timeTransformOut)}.String())

// SERIALIZATION
err = s.Serialize(w, r, ans)
if err != nil {
err = s.ErrorHandler(err)
s.SerializeError(w, r, err)
}
w.Header().Add("Server-Timing", Timing{"serialize", time.Since(timeAfterTransformOut), ""}.String())
w.Header().Add("Server-Timing", Timing{"serialize", "", time.Since(timeAfterTransformOut)}.String())
}
}
51 changes: 27 additions & 24 deletions server.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,13 +15,13 @@ import (
)

type OpenAPIConfig struct {
DisableSwagger bool // If true, the server will not serve the Swagger UI nor the OpenAPI JSON spec
DisableSwaggerUI bool // If true, the server will not serve the Swagger UI
DisableLocalSave bool // If true, the server will not save the OpenAPI JSON spec locally
SwaggerUrl string // URL to serve the swagger UI
UIHandler func(specURL string) http.Handler // Handler to serve the OpenAPI UI from spec URL
SwaggerUrl string // URL to serve the swagger UI
JsonUrl string // URL to serve the OpenAPI JSON spec
JsonFilePath string // Local path to save the OpenAPI JSON spec
DisableSwagger bool // If true, the server will not serve the Swagger UI nor the OpenAPI JSON spec
DisableSwaggerUI bool // If true, the server will not serve the Swagger UI
DisableLocalSave bool // If true, the server will not save the OpenAPI JSON spec locally
PrettyFormatJson bool // Pretty prints the OpenAPI spec with proper JSON indentation
}

Expand All @@ -33,6 +33,10 @@ var defaultOpenAPIConfig = OpenAPIConfig{
}

type Server struct {
startTime time.Time

fs fs.FS

// The underlying HTTP server
*http.Server

Expand All @@ -46,38 +50,37 @@ type Server struct {
// For example, it allows OPTIONS /foo even if it is not declared (only GET /foo is declared).
corsMiddleware func(http.Handler) http.Handler

// routeOptions is used to store the options
// that will be applied of the route.
routeOptions []func(*BaseRoute)

middlewares []func(http.Handler) http.Handler

disableStartupMessages bool
disableAutoGroupTags bool
basePath string // Base path of the group

*Engine

Security Security

autoAuth AutoAuthConfig
fs fs.FS
template *template.Template // TODO: use preparsed templates

// If true, the server will return an error if the request body contains unknown fields. Useful for quick debugging in development.
DisallowUnknownFields bool
maxBodySize int64

// Custom serializer that overrides the default one.
Serialize Sender
// Used to serialize the error response. Defaults to [SendError].
SerializeError ErrorSender

startTime time.Time
Security Security

autoAuth AutoAuthConfig

basePath string // Base path of the group

OpenAPIConfig OpenAPIConfig

isTLS bool
// routeOptions is used to store the options
// that will be applied of the route.
routeOptions []func(*BaseRoute)

middlewares []func(http.Handler) http.Handler

maxBodySize int64

// If true, the server will return an error if the request body contains unknown fields. Useful for quick debugging in development.
DisallowUnknownFields bool

disableStartupMessages bool
disableAutoGroupTags bool
isTLS bool
}

// NewServer creates a new server with the given options.
Expand Down

0 comments on commit a44aa13

Please sign in to comment.