diff --git a/internal/api/album.go b/internal/api/album.go index da007d3e0..2afefb3e6 100644 --- a/internal/api/album.go +++ b/internal/api/album.go @@ -15,6 +15,7 @@ import ( "github.com/photoprism/photoprism/internal/event" "github.com/photoprism/photoprism/internal/form" "github.com/photoprism/photoprism/internal/query" + "github.com/photoprism/photoprism/internal/service" "github.com/photoprism/photoprism/internal/thumb" "github.com/photoprism/photoprism/pkg/fs" "github.com/photoprism/photoprism/pkg/rnd" @@ -429,7 +430,7 @@ func AlbumThumbnail(router *gin.RouterGroup, conf *config.Config) { return } - gc := conf.Cache() + gc := service.Cache() cacheKey := fmt.Sprintf("album-thumbnail:%s:%s", uuid, typeName) if cacheData, ok := gc.Get(cacheKey); ok { diff --git a/internal/api/folder.go b/internal/api/folder.go index 3ed51ab01..b8bf14aee 100644 --- a/internal/api/folder.go +++ b/internal/api/folder.go @@ -1,11 +1,14 @@ package api import ( + "fmt" "net/http" + "time" "github.com/gin-gonic/gin" "github.com/photoprism/photoprism/internal/config" "github.com/photoprism/photoprism/internal/entity" + "github.com/photoprism/photoprism/internal/service" ) // GetFolders is a reusable request handler for directory listings (GET /api/v1/folders/*). @@ -16,12 +19,26 @@ func GetFolders(router *gin.RouterGroup, conf *config.Config, root, pathName str return } + start := time.Now() + gc := service.Cache() recursive := c.Query("recursive") != "" + cacheKey := fmt.Sprintf("folders:%s:%t", pathName, recursive) + + if cacheData, ok := gc.Get(cacheKey); ok { + log.Debugf("folders: %s cache hit [%s]", cacheKey, time.Since(start)) + c.JSON(http.StatusOK, cacheData.([]entity.Folder)) + return + } + folders, err := entity.Folders(root, pathName, recursive) if err != nil { - log.Errorf("folder: %s", err) + log.Errorf("folders: %s", err) + } else { + gc.Set(cacheKey, folders, time.Minute*5) + + log.Debugf("folders: %s cached [%s]", cacheKey, time.Since(start)) } c.JSON(http.StatusOK, folders) diff --git a/internal/api/label.go b/internal/api/label.go index 0276687b5..c443f086a 100644 --- a/internal/api/label.go +++ b/internal/api/label.go @@ -15,6 +15,7 @@ import ( "github.com/photoprism/photoprism/internal/event" "github.com/photoprism/photoprism/internal/form" "github.com/photoprism/photoprism/internal/query" + "github.com/photoprism/photoprism/internal/service" "github.com/photoprism/photoprism/internal/thumb" "github.com/photoprism/photoprism/pkg/fs" "github.com/photoprism/photoprism/pkg/txt" @@ -175,7 +176,7 @@ func LabelThumbnail(router *gin.RouterGroup, conf *config.Config) { return } - gc := conf.Cache() + gc := service.Cache() cacheKey := fmt.Sprintf("label-thumbnail:%s:%s", labelUUID, typeName) if cacheData, ok := gc.Get(cacheKey); ok { diff --git a/internal/service/cache.go b/internal/service/cache.go new file mode 100644 index 000000000..0571ca274 --- /dev/null +++ b/internal/service/cache.go @@ -0,0 +1,20 @@ +package service + +import ( + "sync" + "time" + + gc "github.com/patrickmn/go-cache" +) + +var onceCache sync.Once + +func initCache() { + services.Cache = gc.New(336*time.Hour, 30*time.Minute) +} + +func Cache() *gc.Cache { + onceCache.Do(initCache) + + return services.Cache +} diff --git a/internal/service/service.go b/internal/service/service.go index 2c671ee8c..855699626 100644 --- a/internal/service/service.go +++ b/internal/service/service.go @@ -1,6 +1,7 @@ package service import ( + gc "github.com/patrickmn/go-cache" "github.com/photoprism/photoprism/internal/classify" "github.com/photoprism/photoprism/internal/config" "github.com/photoprism/photoprism/internal/nsfw" @@ -12,6 +13,7 @@ import ( var conf *config.Config var services struct { + Cache *gc.Cache Classify *classify.TensorFlow Convert *photoprism.Convert Import *photoprism.Import