From c3f471817a2f02bfeef5aa801ded32b5b011e80e Mon Sep 17 00:00:00 2001 From: ferreo Date: Mon, 29 Jul 2024 16:39:11 +0100 Subject: [PATCH] Optimise handler response times --- go.mod | 3 +++ go.sum | 6 ++++++ handlers/packages/counts.go | 22 ++++++++++++++++++++-- handlers/packages/packages.go | 24 +++++++++++++++++++++--- helpers/cache.go | 13 +++++++++++++ packages/packages.go | 3 +++ server.go | 19 +++++++++++++++---- 7 files changed, 81 insertions(+), 9 deletions(-) create mode 100644 helpers/cache.go diff --git a/go.mod b/go.mod index 885e920..6ad8652 100644 --- a/go.mod +++ b/go.mod @@ -7,6 +7,7 @@ require ( github.com/gofiber/fiber/v2 v2.52.5 github.com/jinzhu/now v1.1.5 github.com/klauspost/compress v1.17.9 + github.com/maypok86/otter v1.2.1 github.com/samber/slog-fiber v1.16.0 github.com/ulikunitz/xz v0.5.12 golang.org/x/crypto v0.14.0 @@ -17,6 +18,8 @@ require ( require ( 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/jinzhu/inflection v1.0.0 // indirect github.com/mattn/go-colorable v0.1.13 // indirect diff --git a/go.sum b/go.sum index f0ac750..902fe68 100644 --- a/go.sum +++ b/go.sum @@ -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/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/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/go.mod h1:oq7eo15ShAhp70Anwd5lgX2pLfOS3QCiwU/PULtXL6M= 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-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/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/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/rivo/uniseg v0.2.0 h1:S1pD9weZBuJdFmowNwbpi7BJ8TNftyUImj/0WQi72jY= diff --git a/handlers/packages/counts.go b/handlers/packages/counts.go index 51d34ab..000f63e 100644 --- a/handlers/packages/counts.go +++ b/handlers/packages/counts.go @@ -1,11 +1,29 @@ package handlers_packages import ( + "brunel/domain" + "brunel/helpers" "brunel/packages" + "time" "github.com/gofiber/fiber/v2" ) -func Counts(c *fiber.Ctx) error { - return c.Status(fiber.StatusOK).JSON(packages.GetPackagesCount()) +type CountsResponse struct { + 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) } diff --git a/handlers/packages/packages.go b/handlers/packages/packages.go index fb6e270..603c91d 100644 --- a/handlers/packages/packages.go +++ b/handlers/packages/packages.go @@ -3,19 +3,31 @@ package handlers_packages import ( "brunel/domain" "brunel/fastmap" + "brunel/helpers" "brunel/packages" + "fmt" "sort" "strings" "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 { - pageNum := c.QueryInt("page", 1) // Default to 1 if not provided - pageSize := c.QueryInt("pageSize", 250) // Default to 250 if not provided + pageNum := c.QueryInt("page", 1) + pageSize := c.QueryInt("pageSize", 250) search := strings.ToLower(c.Query("search")) 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 adjustedPageNum := pageNum - 1 if adjustedPageNum < 0 { @@ -68,5 +80,11 @@ func Packages(c *fiber.Ctx) error { 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) } diff --git a/helpers/cache.go b/helpers/cache.go new file mode 100644 index 0000000..49ec55b --- /dev/null +++ b/helpers/cache.go @@ -0,0 +1,13 @@ +package helpers + +import ( + "github.com/maypok86/otter" +) + +var ( + Cache otter.Cache[string, any] +) + +func ReloadCache() { + Cache.Clear() +} diff --git a/packages/packages.go b/packages/packages.go index fd5b411..9a8be3b 100644 --- a/packages/packages.go +++ b/packages/packages.go @@ -46,6 +46,7 @@ func ProcessPackages() error { }) LastUpdateTime = time.Now() + helpers.ReloadCache() err = SaveToDb() if err != nil { return err @@ -90,6 +91,7 @@ func saveSingleToDb(pkg domain.SourcePackage) error { return err } LastUpdateTime = time.Now() + helpers.ReloadCache() err = helpers.DBInst.UpdateLastUpdateTime(LastUpdateTime) if err != nil { return err @@ -104,6 +106,7 @@ func SaveToDb() error { return err } LastUpdateTime = time.Now() + helpers.ReloadCache() return helpers.DBInst.UpdateLastUpdateTime(LastUpdateTime) } diff --git a/server.go b/server.go index be25638..2041236 100644 --- a/server.go +++ b/server.go @@ -15,16 +15,25 @@ import ( "github.com/goccy/go-json" "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/maypok86/otter" slogfiber "github.com/samber/slog-fiber" ) // runServer runs a new HTTP server with the loaded environment variables. func runServer(ctx context.Context) error { 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 { slog.Error("unable to load configuration: " + err.Error()) return err @@ -77,7 +86,9 @@ func runServer(ctx context.Context) error { WithTraceID: true, })) server.Use(recover.New()) - server.Use(etag.New()) + server.Use(compress.New(compress.Config{ + Level: compress.LevelBestSpeed, + })) adminRoutes := server.Group("api/admin") adminRoutes.Use(middleware.NewAuth()) @@ -89,5 +100,5 @@ func runServer(ctx context.Context) error { adminRoutes.Post("/register", handlers_auth.Register) 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)) }