Optimise handler response times

This commit is contained in:
ferreo 2024-07-29 16:39:11 +01:00
parent dd2e4bfab5
commit c3f471817a
7 changed files with 81 additions and 9 deletions

3
go.mod
View File

@ -7,6 +7,7 @@ require (
github.com/gofiber/fiber/v2 v2.52.5 github.com/gofiber/fiber/v2 v2.52.5
github.com/jinzhu/now v1.1.5 github.com/jinzhu/now v1.1.5
github.com/klauspost/compress v1.17.9 github.com/klauspost/compress v1.17.9
github.com/maypok86/otter v1.2.1
github.com/samber/slog-fiber v1.16.0 github.com/samber/slog-fiber v1.16.0
github.com/ulikunitz/xz v0.5.12 github.com/ulikunitz/xz v0.5.12
golang.org/x/crypto v0.14.0 golang.org/x/crypto v0.14.0
@ -17,6 +18,8 @@ require (
require ( require (
github.com/andybalholm/brotli v1.0.5 // indirect github.com/andybalholm/brotli v1.0.5 // indirect
github.com/dolthub/maphash v0.1.0 // indirect
github.com/gammazero/deque v0.2.1 // indirect
github.com/google/uuid v1.5.0 // indirect github.com/google/uuid v1.5.0 // indirect
github.com/jinzhu/inflection v1.0.0 // indirect github.com/jinzhu/inflection v1.0.0 // indirect
github.com/mattn/go-colorable v0.1.13 // indirect github.com/mattn/go-colorable v0.1.13 // indirect

6
go.sum
View File

@ -2,6 +2,10 @@ github.com/andybalholm/brotli v1.0.5 h1:8uQZIdzKmjc/iuPu7O2ioW48L81FgatrcpfFmiq/
github.com/andybalholm/brotli v1.0.5/go.mod h1:fO7iG3H7G2nSZ7m0zPUDn85XEX2GTukHGRSepvi9Eig= github.com/andybalholm/brotli v1.0.5/go.mod h1:fO7iG3H7G2nSZ7m0zPUDn85XEX2GTukHGRSepvi9Eig=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/dolthub/maphash v0.1.0 h1:bsQ7JsF4FkkWyrP3oCnFJgrCUAFbFf3kOl4L/QxPDyQ=
github.com/dolthub/maphash v0.1.0/go.mod h1:gkg4Ch4CdCDu5h6PMriVLawB7koZ+5ijb9puGMV50a4=
github.com/gammazero/deque v0.2.1 h1:qSdsbG6pgp6nL7A0+K/B7s12mcCY/5l5SIUpMOl+dC0=
github.com/gammazero/deque v0.2.1/go.mod h1:LFroj8x4cMYCukHJDbxFCkT+r9AndaJnFMuZDV34tuU=
github.com/goccy/go-json v0.10.3 h1:KZ5WoDbxAIgm2HNbYckL0se1fHD6rz5j4ywS6ebzDqA= github.com/goccy/go-json v0.10.3 h1:KZ5WoDbxAIgm2HNbYckL0se1fHD6rz5j4ywS6ebzDqA=
github.com/goccy/go-json v0.10.3/go.mod h1:oq7eo15ShAhp70Anwd5lgX2pLfOS3QCiwU/PULtXL6M= github.com/goccy/go-json v0.10.3/go.mod h1:oq7eo15ShAhp70Anwd5lgX2pLfOS3QCiwU/PULtXL6M=
github.com/gofiber/fiber/v2 v2.52.5 h1:tWoP1MJQjGEe4GB5TUGOi7P2E0ZMMRx5ZTG4rT+yGMo= github.com/gofiber/fiber/v2 v2.52.5 h1:tWoP1MJQjGEe4GB5TUGOi7P2E0ZMMRx5ZTG4rT+yGMo=
@ -25,6 +29,8 @@ github.com/mattn/go-runewidth v0.0.15 h1:UNAjwbU9l54TA3KzvqLGxwWjHmMgBUVhBiTjelZ
github.com/mattn/go-runewidth v0.0.15/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w= github.com/mattn/go-runewidth v0.0.15/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w=
github.com/mattn/go-sqlite3 v1.14.22 h1:2gZY6PC6kBnID23Tichd1K+Z0oS6nE/XwU+Vz/5o4kU= github.com/mattn/go-sqlite3 v1.14.22 h1:2gZY6PC6kBnID23Tichd1K+Z0oS6nE/XwU+Vz/5o4kU=
github.com/mattn/go-sqlite3 v1.14.22/go.mod h1:Uh1q+B4BYcTPb+yiD3kU8Ct7aC0hY9fxUwlHK0RXw+Y= github.com/mattn/go-sqlite3 v1.14.22/go.mod h1:Uh1q+B4BYcTPb+yiD3kU8Ct7aC0hY9fxUwlHK0RXw+Y=
github.com/maypok86/otter v1.2.1 h1:xyvMW+t0vE1sKt/++GTkznLitEl7D/msqXkAbLwiC1M=
github.com/maypok86/otter v1.2.1/go.mod h1:mKLfoI7v1HOmQMwFgX4QkRk23mX6ge3RDvjdHOWG4R4=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/rivo/uniseg v0.2.0 h1:S1pD9weZBuJdFmowNwbpi7BJ8TNftyUImj/0WQi72jY= github.com/rivo/uniseg v0.2.0 h1:S1pD9weZBuJdFmowNwbpi7BJ8TNftyUImj/0WQi72jY=

View File

@ -1,11 +1,29 @@
package handlers_packages package handlers_packages
import ( import (
"brunel/domain"
"brunel/helpers"
"brunel/packages" "brunel/packages"
"time"
"github.com/gofiber/fiber/v2" "github.com/gofiber/fiber/v2"
) )
func Counts(c *fiber.Ctx) error { type CountsResponse struct {
return c.Status(fiber.StatusOK).JSON(packages.GetPackagesCount()) LastUpdateTime time.Time `json:"lastUpdateTime"`
Counts domain.PackagesCount `json:"counts"`
}
func Counts(c *fiber.Ctx) error {
if cachedResponse, ok := helpers.Cache.Get("counts"); ok {
return c.Status(fiber.StatusOK).JSON(cachedResponse)
}
response := CountsResponse{
LastUpdateTime: packages.LastUpdateTime,
Counts: packages.GetPackagesCount(),
}
helpers.Cache.Set("counts", response)
return c.Status(fiber.StatusOK).JSON(response)
} }

View File

@ -3,19 +3,31 @@ package handlers_packages
import ( import (
"brunel/domain" "brunel/domain"
"brunel/fastmap" "brunel/fastmap"
"brunel/helpers"
"brunel/packages" "brunel/packages"
"fmt"
"sort" "sort"
"strings" "strings"
"github.com/gofiber/fiber/v2" "github.com/gofiber/fiber/v2"
) )
type PackagesResponse struct {
Total int `json:"total"`
Packages *fastmap.Fastmap[string, domain.SourcePackage] `json:"packages"`
}
func Packages(c *fiber.Ctx) error { func Packages(c *fiber.Ctx) error {
pageNum := c.QueryInt("page", 1) // Default to 1 if not provided pageNum := c.QueryInt("page", 1)
pageSize := c.QueryInt("pageSize", 250) // Default to 250 if not provided pageSize := c.QueryInt("pageSize", 250)
search := strings.ToLower(c.Query("search")) search := strings.ToLower(c.Query("search"))
filter := c.Query("filter") filter := c.Query("filter")
cacheKey := fmt.Sprintf("packages:%d:%d:%s:%s", pageNum, pageSize, search, filter)
if cachedResponse, ok := helpers.Cache.Get(cacheKey); ok {
return c.Status(fiber.StatusOK).JSON(cachedResponse)
}
// Adjust pageNum to be 0-based for GetPage // Adjust pageNum to be 0-based for GetPage
adjustedPageNum := pageNum - 1 adjustedPageNum := pageNum - 1
if adjustedPageNum < 0 { if adjustedPageNum < 0 {
@ -68,5 +80,11 @@ func Packages(c *fiber.Ctx) error {
result := finalReturn.GetPage(adjustedPageNum, pageSize) result := finalReturn.GetPage(adjustedPageNum, pageSize)
return c.Status(fiber.StatusOK).JSON(result) response := PackagesResponse{
Total: finalReturn.Len(),
Packages: result,
}
helpers.Cache.Set(cacheKey, response)
return c.Status(fiber.StatusOK).JSON(response)
} }

13
helpers/cache.go Normal file
View File

@ -0,0 +1,13 @@
package helpers
import (
"github.com/maypok86/otter"
)
var (
Cache otter.Cache[string, any]
)
func ReloadCache() {
Cache.Clear()
}

View File

@ -46,6 +46,7 @@ func ProcessPackages() error {
}) })
LastUpdateTime = time.Now() LastUpdateTime = time.Now()
helpers.ReloadCache()
err = SaveToDb() err = SaveToDb()
if err != nil { if err != nil {
return err return err
@ -90,6 +91,7 @@ func saveSingleToDb(pkg domain.SourcePackage) error {
return err return err
} }
LastUpdateTime = time.Now() LastUpdateTime = time.Now()
helpers.ReloadCache()
err = helpers.DBInst.UpdateLastUpdateTime(LastUpdateTime) err = helpers.DBInst.UpdateLastUpdateTime(LastUpdateTime)
if err != nil { if err != nil {
return err return err
@ -104,6 +106,7 @@ func SaveToDb() error {
return err return err
} }
LastUpdateTime = time.Now() LastUpdateTime = time.Now()
helpers.ReloadCache()
return helpers.DBInst.UpdateLastUpdateTime(LastUpdateTime) return helpers.DBInst.UpdateLastUpdateTime(LastUpdateTime)
} }

View File

@ -15,16 +15,25 @@ import (
"github.com/goccy/go-json" "github.com/goccy/go-json"
"github.com/gofiber/fiber/v2" "github.com/gofiber/fiber/v2"
"github.com/gofiber/fiber/v2/middleware/etag" "github.com/gofiber/fiber/v2/middleware/compress"
"github.com/gofiber/fiber/v2/middleware/recover" "github.com/gofiber/fiber/v2/middleware/recover"
"github.com/maypok86/otter"
slogfiber "github.com/samber/slog-fiber" slogfiber "github.com/samber/slog-fiber"
) )
// runServer runs a new HTTP server with the loaded environment variables. // runServer runs a new HTTP server with the loaded environment variables.
func runServer(ctx context.Context) error { func runServer(ctx context.Context) error {
logger := slog.New(slog.NewTextHandler(os.Stdout, nil)) logger := slog.New(slog.NewTextHandler(os.Stdout, nil))
var err error
err := config.Init() ott := otter.MustBuilder[string, any](10000)
ott.WithTTL(time.Hour * 24)
helpers.Cache, err = ott.Build()
if err != nil {
panic(err)
}
err = config.Init()
if err != nil { if err != nil {
slog.Error("unable to load configuration: " + err.Error()) slog.Error("unable to load configuration: " + err.Error())
return err return err
@ -77,7 +86,9 @@ func runServer(ctx context.Context) error {
WithTraceID: true, WithTraceID: true,
})) }))
server.Use(recover.New()) server.Use(recover.New())
server.Use(etag.New()) server.Use(compress.New(compress.Config{
Level: compress.LevelBestSpeed,
}))
adminRoutes := server.Group("api/admin") adminRoutes := server.Group("api/admin")
adminRoutes.Use(middleware.NewAuth()) adminRoutes.Use(middleware.NewAuth())
@ -89,5 +100,5 @@ func runServer(ctx context.Context) error {
adminRoutes.Post("/register", handlers_auth.Register) adminRoutes.Post("/register", handlers_auth.Register)
adminRoutes.Post("/updatePassword", handlers_auth.UpdatePassword) adminRoutes.Post("/updatePassword", handlers_auth.UpdatePassword)
return server.Listen(fmt.Sprintf(":%d", config.Configs.Port)) return server.Listen(fmt.Sprintf("localhost:%d", config.Configs.Port))
} }