Optimise handler response times
This commit is contained in:
parent
dd2e4bfab5
commit
c3f471817a
3
go.mod
3
go.mod
@ -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
6
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/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=
|
||||||
|
@ -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)
|
||||||
}
|
}
|
||||||
|
@ -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
13
helpers/cache.go
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
package helpers
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/maypok86/otter"
|
||||||
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
Cache otter.Cache[string, any]
|
||||||
|
)
|
||||||
|
|
||||||
|
func ReloadCache() {
|
||||||
|
Cache.Clear()
|
||||||
|
}
|
@ -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)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
19
server.go
19
server.go
@ -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))
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user