1
0
mirror of https://github.com/muety/wakapi.git synced 2023-08-10 21:12:56 +03:00

chore: cache avatars in memory

This commit is contained in:
Ferdinand Mütsch 2022-02-17 10:34:33 +01:00
parent 660a09475e
commit 222024dabb
4 changed files with 29 additions and 11 deletions

1
go.mod
View File

@ -17,6 +17,7 @@ require (
github.com/gorilla/mux v1.8.0 github.com/gorilla/mux v1.8.0
github.com/gorilla/schema v1.2.0 github.com/gorilla/schema v1.2.0
github.com/gorilla/securecookie v1.1.1 github.com/gorilla/securecookie v1.1.1
github.com/hashicorp/golang-lru v0.5.4
github.com/jackc/pgx/v4 v4.14.1 // indirect github.com/jackc/pgx/v4 v4.14.1 // indirect
github.com/jinzhu/configor v1.2.1 github.com/jinzhu/configor v1.2.1
github.com/jinzhu/now v1.1.4 // indirect github.com/jinzhu/now v1.1.4 // indirect

2
go.sum
View File

@ -109,6 +109,8 @@ github.com/gorilla/securecookie v1.1.1 h1:miw7JPhV+b/lAHSXz4qd/nN9jRiAFV5FwjeKyC
github.com/gorilla/securecookie v1.1.1/go.mod h1:ra0sb63/xPlUeL+yeDciTfxMRAA+MP+HVt/4epWDjd4= github.com/gorilla/securecookie v1.1.1/go.mod h1:ra0sb63/xPlUeL+yeDciTfxMRAA+MP+HVt/4epWDjd4=
github.com/gorilla/websocket v1.4.1/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= github.com/gorilla/websocket v1.4.1/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
github.com/hashicorp/go-version v1.2.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= github.com/hashicorp/go-version v1.2.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA=
github.com/hashicorp/golang-lru v0.5.4 h1:YDjusn29QI/Das2iO9M0BHnIbxPeyuCHsjMW+lJfyTc=
github.com/hashicorp/golang-lru v0.5.4/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uGBxy+E8yxSoD4=
github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ= github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ=
github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
github.com/imkira/go-interpol v1.1.0/go.mod h1:z0h2/2T3XF8kyEPpRgJ3kmNv+C43p+I/CoI+jC3w2iA= github.com/imkira/go-interpol v1.1.0/go.mod h1:z0h2/2T3XF8kyEPpRgJ3kmNv+C43p+I/CoI+jC3w2iA=

View File

@ -3,16 +3,26 @@ package api
import ( import (
"codeberg.org/Codeberg/avatars" "codeberg.org/Codeberg/avatars"
"github.com/gorilla/mux" "github.com/gorilla/mux"
lru "github.com/hashicorp/golang-lru"
conf "github.com/muety/wakapi/config" conf "github.com/muety/wakapi/config"
"net/http" "net/http"
) )
type AvatarHandler struct { type AvatarHandler struct {
config *conf.Config config *conf.Config
cache *lru.Cache
} }
func NewAvatarHandler() *AvatarHandler { func NewAvatarHandler() *AvatarHandler {
return &AvatarHandler{config: conf.Get()} cache, err := lru.New(1 * 1000 * 64) // assuming an avatar is 1 kb, allocate up to 64 mb of memory for avatars cache
if err != nil {
panic(err)
}
return &AvatarHandler{
config: conf.Get(),
cache: cache,
}
} }
func (h *AvatarHandler) RegisterRoutes(router *mux.Router) { func (h *AvatarHandler) RegisterRoutes(router *mux.Router) {
@ -21,15 +31,15 @@ func (h *AvatarHandler) RegisterRoutes(router *mux.Router) {
} }
func (h *AvatarHandler) Get(w http.ResponseWriter, r *http.Request) { func (h *AvatarHandler) Get(w http.ResponseWriter, r *http.Request) {
vars := mux.Vars(r) hash := mux.Vars(r)["hash"]
if vars["hash"] == "" { if !h.cache.Contains(hash) {
w.WriteHeader(http.StatusNotFound) h.cache.Add(hash, avatars.MakeMaleAvatar(hash))
w.Write([]byte{})
return
} }
data, _ := h.cache.Get(hash)
w.Header().Set("Content-Type", "image/svg+xml") w.Header().Set("Content-Type", "image/svg+xml")
w.Header().Set("Cache-Control", "max-age=2592000")
w.WriteHeader(http.StatusOK) w.WriteHeader(http.StatusOK)
w.Write([]byte(avatars.MakeMaleAvatar(vars["hash"]))) w.Write([]byte(data.(string)))
} }

View File

@ -1,23 +1,28 @@
package fs package fs
import ( import (
"github.com/patrickmn/go-cache" lru "github.com/hashicorp/golang-lru"
"io/fs" "io/fs"
"net/http" "net/http"
"strings" "strings"
) )
func NewExistsFS(fs fs.FS) ExistsFS { func NewExistsFS(fs fs.FS) ExistsFS {
cache, err := lru.New(1 << 24)
if err != nil {
panic(err)
}
return ExistsFS{ return ExistsFS{
FS: fs, FS: fs,
cache: cache.New(cache.NoExpiration, cache.NoExpiration), cache: cache,
} }
} }
type ExistsFS struct { type ExistsFS struct {
fs.FS fs.FS
UseCache bool UseCache bool
cache *cache.Cache cache *lru.Cache
} }
func (efs ExistsFS) WithCache(withCache bool) ExistsFS { func (efs ExistsFS) WithCache(withCache bool) ExistsFS {
@ -34,7 +39,7 @@ func (efs ExistsFS) Exists(name string) bool {
_, err := fs.Stat(efs.FS, name) _, err := fs.Stat(efs.FS, name)
result := err == nil result := err == nil
if efs.UseCache { if efs.UseCache {
efs.cache.SetDefault(name, result) efs.cache.Add(name, result)
} }
return result return result
} }